Ответ 1
То, что вы видите здесь, связано с тем, что объявления верхнего уровня без аргументов мономорфны. Вы можете найти некоторое обсуждение причин этого в Haskell wiki и некоторую информацию о контролируя это поведение в руководстве пользователя GHC.
В качестве иллюстрации обратите внимание, что предоставление len
аргумента устраняет проблему:
len x = genericLength x
> :t len
len :: Num i => [b] -> i
Таким образом, он дает подпись типа:
len :: (Num b) => [a] -> b
len = genericLength
Таким же образом отключается ограничение мономорфизма:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.List (genericLength)
len = genericLength
> :t len
len :: Num i => [b] -> i
В этом конкретном случае, я думаю, вы также получаете другой тип (а не ошибку компилятора) из-за правил по умолчанию, которые указывают, что определенные классы классов должны по умолчанию задавать конкретные типы (в этом случае Num
по умолчанию Integer
Если вы попытаетесь сделать то же самое с fmap
, вы получите следующее:
> :r
[1 of 1] Compiling Main ( MonoTest.hs, interpreted )
MonoTest.hs:4:5:
Ambiguous type variable `f0' in the constraint:
(Functor f0) arising from a use of `fmap'
Possible cause: the monomorphism restriction applied to the following:
f :: forall a b. (a -> b) -> f0 a -> f0 b
(bound at MonoTest.hs:4:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the expression: fmap
In an equation for `f': f = fmap
Failed, modules loaded: none.
Вы можете найти информацию о дефолте в Haskell 98 Report. Я также упомянул, что GHC поддерживает расширенную форму дефолта, которая в основном используется для GHCi (и включена там по умолчанию), что иногда путает людей.