Как происходит расчет типов в Haskell


Скажем

  flip :: (a->b->c) ->b->a->c
  const ::d->e->d

Тип (flip const) будет

  a=d,b=e,c=d

В

  b->a->c

Таким образом, тип будет

  e->d->d

Но для (карты взять) его

  [Int]->[[a]]->[[a]]

Поэтому я не понял, как вычисляется ghci на этот раз. я понял [[a]] - >[[a]] но почему и как [Int]?

Edit: например, если бы мы писали в ghci

  :t flip const 


it would return b->c->c

И ghci вычислит это так же, как и я.

Но

 map :: (a->b)->[a]->[b]
 take :: Int->[c]->[c]

Так почему же карта take

  [Int]->[[a]->[a]]

Почему [Int] как это произошло? ghci вычислить, что

2 6

2 ответа:

Вы должны скопировать и вставить типы, которые вы видите, а не повторно вводить их в вопрос. Причина в том, что вы видели неправильно. Тип для map take:

map take :: [Int] -> [[a] -> [a]]
Другими словами, объединение работает как таковое:
:t map
map :: (a -> b) -> [a] -> [b]
:t take
take :: Int -> [c] -> [c]
Таким образом, при применении take в качестве первого аргумента к map Вы получаете a ~ Int и b ~ [c] -> [c] (обратите внимание, что это функция). Выполнение этих замен в типе map и применение первого аргумента:
map take :: [a] -> [b]        (for some specific 'a' and 'b')
-- recall a ~ Int
map take :: [Int] -> [b]      (for some specific 'b')
-- recall b ~ [c] -> [c]
map take :: [Int] -> [[c] -> [c]]

Да, map take это именно то, что вы ожидаете. Функция, которая работает над списками Int и приводит к списку функций, которые будут принимать некоторое количество элементов от начала списка.

Давайте проведем тот же анализ:

map :: (a -> b) -> [a] -> [b]

И

take :: Int -> [x] -> [x]

Но на самом деле это означает

take :: Int -> ([x] -> [x])

Так что с a=Int и b=([x] -> [x]) вы получите

map take :: [Int] -> [ [x] -> [x] ]

Список функций списка!