Основываясь на том, что я прочитал о Haskell, и эксперименте, который я провел с GHC, кажется, что Haskell имеет перегрузку типа возвращаемого типа (так называемый ad hoc полиморфизм). Одним из примеров этого является функция fromInteger
, которая может дать вам Double
или Integer
в зависимости от того, где используется результат. Например:
fd :: Double -> String
fd x = "Double"
fi :: Integer -> String
fi x = "Integer"
fd (fromInteger 5) -- returns "Double"
fi (fromInteger 5) -- returns "Integer"
Нежное введение в Haskell, похоже, соглашается с этим, когда говорится:
Тип полиморфизма, о котором мы говорили до сих пор, обычно называют параметрическим полиморфизмом. Существует еще один вид, называемый ad hoc-полиморфизм, более известный как перегрузка. Вот несколько примеров ad hoc-полиморфизма:
- Литералы 1, 2 и т.д. часто используются для представления как фиксированных, так и произвольных целых чисел точности.
Если числовые литералы считаются примером ad hoc-полиморфизма (aka overloading), то кажется, что то же самое верно для результата таких функций, как fromInteger
.
И на самом деле, я нашел несколько ответов на другие вопросы о переполнении стека, которые предполагают, что Haskell имеет перегрузку по типу возврата.
Однако, по крайней мере один программист Haskell сказал мне, что это не перегрузка возвращаемого типа, а вместо этого является примером "параметрического полиморфизма, где параметр связан универсальным квантором".
Я думаю, что он получает то, что fromInteger
возвращает значение из каждого экземпляра Num
(своего рода недетерминированный тип).
Это кажется разумной интерпретацией, но, насколько я могу судить, Haskell никогда не позволяет нам смотреть на более чем одно из этих значений экземпляров (частично благодаря Ограничение мономорфизма). Также кажется, что фактический экземпляр, значение которого мы смотрим, можно определить статически. Из-за всего этого представляется разумным сказать, что в выражении fd (fromInteger 5)
подвыражение fromInteger 5
имеет тип Double
, тогда как в выражении fi (fromInteger 5)
подвыражение fromInteger 5
имеет тип Integer
.
Итак, имеет ли Haskell перегрузку типа возвращаемого типа?
Если нет, укажите пример одного из следующих действий:
- действительный код Haskell, который имел бы другое поведение, если Haskell возвращал тип перегрузки
- действительный код Haskell, который был бы недопустимым, если Haskell возвращал тип перегрузки
- недопустимый код Haskell, который был бы действителен, если Haskell возвращал тип перегрузки