haskell - 为什么 `let foo = (fmap . const)` 失败并显示 "No instance for (Functor f0) arising from a use of ` fmap'"?

标签 haskell type-inference

在 ghci 我可以这样做:

ghci> (fmap . const) 5 [1,2,3,4,5]
[5,5,5,5,5]

但如果我尝试提取子表达式 (fmap . const)进入一个变量我得到一个错误:
ghci> let foo = (fmap . const)

<interactive>:3:12:
    No instance for (Functor f0) arising from a use of `fmap'
    The type variable `f0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Functor ((,) a) -- Defined in `GHC.Base'
      instance Functor ((->) r) -- Defined in `GHC.Base'
      instance Functor IO -- Defined in `GHC.Base'
      ...plus two others
    In the first argument of `(.)', namely `fmap'
    In the expression: (fmap . const)
    In an equation for `foo': foo = (fmap . const)

我认为这可能意味着 GHC 的类型推断以某种方式失败,但是当我单独向 ghci 询问子表达式的类型时,它没有问题:
ghci> :t (fmap . const)
(fmap . const) :: Functor f => b -> f a -> f b

那么这里发生了什么?有没有办法将此子表达式提取到变量中?为什么不直截了当let工作?

更新:

“什么是单态限制”可能是在答案中链接到的好东西(即:“另见......”),但这不是该问题的重复,除非 StackOverflow 已成为某种奇怪的版本游戏节目危险。当我问这个问题时,我已经知道单态限制,但对我来说,MR 是我收到错误的原因并不明显。

这个问题的答案在这方面没有帮助。它说“这意味着,在某些情况下,如果您的类型不明确......编译器将选择将该类型实例化为不明确的东西”,这几乎与这里发生的事情相反(MR 正在制造歧义,不删除它。)

最佳答案

这是可怕的单态性限制。如果你运行 :set -XNoMonomorphismRestriction它会起作用的。您还可以使用像这样的显式类型签名来定义它

foo :: Functor f => b -> f a -> f b
foo = fmap . const

关于haskell - 为什么 `let foo = (fmap . const)` 失败并显示 "No instance for (Functor f0) arising from a use of ` fmap'"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24457140/

相关文章:

haskell - monad的类型构造函数和返回函数之间的区别(在Haskell中)

haskell - Haskell 类型类中的乘积和求和类型并行

compiler-errors - 找到预期的 XYZ ()

templates - 从函数返回类型推断模板参数类型

c++ - 在 C++ 中使用 auto 声明变量有缺点吗?

haskell - 类型正确的功能可以不适用吗? ( haskell )

string - Haskell:将输入字符串直接转换为列表

haskell - 很难理解如何使用 nubBy

haskell - 为什么我不能使用类型 `Show a => [Something -> a]` ?

防止除以 0 的 typescript 类型