Это помогает сделать две вещи прежде всего:
- поставить явные скобки так, чтобы
x->y->z
стало x->(y->z)
- переименовывать переменные типа, чтобы не было конфликтов
С учетом этого давайте перепишем типы
(=<<) :: Monad m => (a -> m b) -> (m a -> m b)
zip :: [x] -> ([y] -> [(x, y)])
Теперь сопоставим типы.Первый аргумент =<<
равен zip
, поэтому (a -> m b)
совпадает с [x] -> ([y] -> [(x, y)])
.
a -> m b
[x] -> ([y] -> [(x, y)])
Так что a
равно [x]
и m b
равно ([y] -> [(x, y)])
.Переписав ->
в префиксной записи, мы получим -> [y] [(x, y)]
, что совпадает с (-> [y]) [(x, y)]
.
m b
(-> [y]) [(x, y)]
Так что m
равно (-> [y])
(что действительно является монадой) и b
это [(x, y)]
.
Итак, теперь мы знаем, что такое a
, что такое b
и что такое m
.Давайте перепишем (m a -> m b)
в следующих терминах:
(m a) -> (m b)
((-> [y]) [x]) -> ((-> [y]) [(x, y)])
Переписав снова в стиле инфикса, мы получим
([y] -> [x]) -> ([y] -> [(x, y)])
, то есть, вплоть до имен переменных, такой же ответ GHCдавая вам.