Рассмотрим следующую функцию Haskell:(Num а) против типа вывода Integer
sign a
| a < 0 = (-1)
| a > 0 = 1
| otherwise = 0
Когда я загружаю это в GHCI я ожидал :t sign
быть:
sign :: (Num a, Ord a) => a -> Integer
Вместо этого выводится как:
*Main> :t sign
sign :: (Num a1, Num a, Ord a1) => a1 -> a
Аналогично, если я попрошу тип целого 5
, я ожидал Integer
, но вместо этого я получил
*Main> :t 5
5 :: Num a => a
Там что-то я не понимая о типах Хаскеля. Дело в том, что если все, что я знаю о типе возвращаемого sign
является то, что он является экземпляром Num
класса типов, то я не должен быть в состоянии передать возвращаемое значение в эту функцию:
double :: Integer -> Integer
double x = x * 2
То есть, для моей функции double
требуется Integer
, а не только для любых экземпляров Num
.
Тем не менее, следующие работы просто отлично:
*Main> double (sign 5.5)
2
Что это такое, что я неправильно понимаю о системе типов в Haskell?
Кстати, есть, конечно, также функция 'signum :: Num a => a -> a', то есть вы передаете число в нее и возвращаете число * одного и того же типа *. – mrueg
Тот факт, что вы передали его 'double', дает двигателю ввода вывода больше знаний - он знает, что он работает с' double', и выясняет, как это сделать. – jpaugh