[英]Why does `let foo = (fmap . const)` fail with “No instance for (Functor f0) arising from a use of `fmap'”?
在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询问subexpresiion的类型时,它没有问题:
ghci> :t (fmap . const)
(fmap . const) :: Functor f => b -> f a -> f b
那么这里发生了什么? 有没有办法将这个子表达式提取到变量中? 为什么不直截了当let
工作?
“什么是单态限制”可能是一个好的东西,在答案中链接(即:“另见......”),但这不是该问题的重复,除非StackOverflow已成为某种奇怪的版本游戏节目Jeopardy。 当我问这个问题时,我已经知道单态性限制了,但对我来说,MR是导致我收到错误的原因一点也不明显。
在这方面,这个问题的答案没有帮助。 它说“这意味着,在某些情况下,如果你的类型不明确......编译器将选择将该类型实例化为不模糊的东西”,这与此处发生的情况几乎相反(MR正在产生歧义,不要删除它。)
这是可怕的单态限制。 如果运行:set -XNoMonomorphismRestriction
它将起作用。 您也可以使用这样的显式类型签名来定义它
foo :: Functor f => b -> f a -> f b
foo = fmap . const
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.