Исходя из Javascript, я понимаю, что тип списка Haskell обеспечивает однородные списки. Теперь это удивило меня, что следующие различные типы функций отвечают этому требованию:
f :: (a -> a) -> a -> a
f g x = g x
g :: (a -> b) -> a -> b
g h x = h x
let xs = [f, g] -- type checks
хотя g
более широко применяется, чем f
:
f(\x -> [x]) "foo" -- type error
g(\x -> [x]) "foo" -- type checks
Не следует обрабатывать (a -> a)
, чем (a -> b)
. Мне кажется, что последний является подтипом первого. Но в Haskell нет подтиповых отношений, верно? Так почему это работает?