简体   繁体   English

为什么`让foo =(fmap.const)`失败“因为使用`fmap'而没有(Functor f0)的实例?

[英]Why does `let foo = (fmap . const)` fail with “No instance for (Functor f0) arising from a use of `fmap'”?

In ghci I can do this: 在ghci,我可以这样做:

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

but if I try to extract the sub-expression (fmap . const) into a variable I get an error: 但如果我尝试将子表达式(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)

I thought this might mean GHC's type inference was failing somehow, but when I ask ghci for the type of the subexpresiion in isolation it has no problem: 我认为这可能意味着GHC的类型推断在某种程度上失败了,但是当我向ghci询问subexpresiion的类型时,它没有问题:

ghci> :t (fmap . const)
(fmap . const) :: Functor f => b -> f a -> f b

So what's going on here? 那么这里发生了什么? Is there any way to extract this subexpression into a variable? 有没有办法将这个子表达式提取到变量中? Why doesn't the straightforward let work? 为什么不直截了当let工作?

Update: 更新:

"What is the monomorphism restriction" might be a good thing to link to in an answer (ie: "See also..."), but this isn't a duplicate of that question unless StackOverflow has become some sort of weird version of the game show Jeopardy. “什么是单态限制”可能是一个好的东西,在答案中链接(即:“另见......”),但这不是该问题的重复,除非StackOverflow已成为某种奇怪的版本游戏节目Jeopardy。 I already knew of the monomorphism restriction when I asked this question, but it was not at all obvious to me that MR was the cause of the error I was receiving. 当我问这个问题时,我已经知道单态性限制了,但对我来说,MR是导致我收到错误的原因一点也不明显。

The answer to that question doesn't help in that regard. 在这方面,这个问题的答案没有帮助。 It says "What this means is that, in some circumstances, if your type is ambiguous ... the compiler will choose to instantiate that type to something not ambiguous", which almost the opposite of what is happening here (MR is creating ambiguity, not removing it.) 它说“这意味着,在某些情况下,如果你的类型不明确......编译器将选择将该类型实例化为不模糊的东西”,这与此处发生的情况几乎相反(MR正在产生歧义,不要删除它。)

It's the dreaded monomorphism restriction. 这是可怕的单态限制。 If you run :set -XNoMonomorphismRestriction it will work. 如果运行:set -XNoMonomorphismRestriction它将起作用。 You can also define it with an explicit type signature like this 您也可以使用这样的显式类型签名来定义它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM