Haskell - fmap fmap不起作用

Maf*_*afi 5 haskell types ghci

我正在使用GHCi(版本6.12.3)与Haskell一起玩.我最近阅读了有关仿函数和应用仿函数的想法,如果你不能<*>使用仿函数的原语来实现类似于applicative仿函数的东西.经过一番思考后我想出了fmap fmap一个(几乎)理想的类型

Functor f => f (a -> b) -> f (f a -> f b) 或者更一般地说

(Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)

我试过了

let q = fmap fmap
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

<interactive>:1:8:
    Ambiguous type variable `f1' in the constraint:
      `Functor f1' arising from a use of `fmap' at <interactive>:1:8-16
    Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:13:
    Ambiguous type variable `f' in the constraint:
      `Functor f' arising from a use of `fmap' at <interactive>:1:13-16
    Probable fix: add a type signature that fixes these type variable(s)
Run Code Online (Sandbox Code Playgroud)

根据建议编写上述类型签名没有帮助.最疯狂的是当我输入时,:t fmap fmap我得到了与上面相同的类型.

我究竟做错了什么?fmap fmap尽管GHCi找到了类型,为什么会出现类型错误?

ham*_*mar 7

看起来你正在遇到单态限制.

在GHCi中尝试您的示例可以获得-XNoMonomorphismRestriction预期的结果.

你也可以通过写作来颠覆这一点let f x = fmap fmap $ x.单态限制仅适用于"看起来像"值的顶级定义,即f = something引入显式参数导致它不再适用.如果不在顶层(例如在where子句中),它也不适用.有关更多详细信息,请参阅链接.