Тип map
: map :: (a -> b) -> [a] -> [b]
. Следовательно, тип map foo
получается из [a] -> [b]
путем замены a
и b
на то, что может быть получено из типа foo
. Если, например, foo :: t -> t
, вы заменяете a = t, b = t
и получаете [t] -> [t]
. Если foo :: [t] -> Int
, вы получаете [[t]] -> [Int]
.
В вашем случае foo
(map
) - (x -> y) -> [x] -> [y]
. Вы должны объединить этот тип с a -> b
, чтобы узнать, что a
и b
должны быть заменены. [Обратите внимание, что функция стрелок правоассоциативный, x -> y -> z = x -> (y -> z)
.]
Чтобы найти тип
\x -> x >>= (\y -> y)
использовать известный тип (>>=) :: Monad m => m a -> (a -> m b) -> m b
. Игнорировать ограничение (Monad m =>
) пока.
В качестве первого аргумента (>>=)
, x
должен иметь тип m a
для неизвестной пока m
и a
. Второй аргумент (>>=)
здесь личность,
(\y -> y) :: t -> t
так что вы должны объединить t -> t
с a -> m b
. Это дает вам некоторую информацию о a
, а именно a = m b
.
Это дает x :: m (m b)
и (\x -> x >>= (\y -> y)) :: type_of_x -> type_of_rhs
.
Наконец, вспомните временно забытое ограничение Monad m =>
.
Это самый удобный для начинающих источник, который я нашел: http://cs.brown.edu/courses/cs173/2012/book/types.html#(part._.Type_.Inference), и есть также это более глубокое объяснение. http://web.cecs.pdx.edu/~antoy/Courses/TPFLP/lectures/TYPE/BasicTypechecking.pdf – Wes