Haskell: вывод типа и состав функции - PullRequest
15 голосов
/ 28 августа 2009

Этот вопрос был вдохновлен этим ответом на другой вопрос, указывающим, что вы можете удалить каждое вхождение элемента из списка с помощью функции, определенной как:

removeall = filter . (/=)

Работая с карандашом и бумагой из типов filter, (/=) и (.), функция имеет тип

removeall :: (Eq a) => a -> [a] -> [a]

это именно то, что вы ожидаете, основываясь на его контракте. Однако с GHCi 6.6 я получаю

gchi> :t removeall
removeall :: Integer -> [Integer] -> [Integer]

если я не укажу тип явно (в этом случае он работает нормально). Почему Haskell выводит такой специфический тип для функции?

Ответы [ 2 ]

28 голосов
/ 28 августа 2009

Почему Haskell выводит такой специфический тип для функции?

GHCi использует тип по умолчанию , чтобы вывести более конкретный тип из набора возможных. Вы можете легко избежать этого, отключив ограничение мономорфизма ,

Prelude> :set -XNoMonomorphismRestriction
Prelude> let removeall = filter . (/=)
Prelude> :t removeall 
removeall :: (Eq a) => a -> [a] -> [a]
17 голосов
/ 28 августа 2009

Стоит также отметить, что если вы не присваиваете имя выражению, типограф проверяет, кажется, тип по умолчанию:

Prelude> :t filter . (/=)
filter . (/=) :: (Eq a) => a -> [a] -> [a]
...