Вопрос

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

removeall = filter . (/=)

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

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

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

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

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

Это было полезно?

Решение

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

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

Prelude> :set -XNoMonomorphismRestriction
Prelude> let removeall = filter . (/=)
Prelude> :t removeall 
removeall :: (Eq a) => a -> [a] -> [a]

Другие советы

Также стоит отметить, что если вы не присваиваете выражению имя, typechecker, похоже, избегает значения типа по умолчанию:

Prelude> :t filter . (/=)
filter . (/=) :: (Eq a) => a -> [a] -> [a]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top