Lau*_*ves 7 haskell type-inference
在ghci,我可以这样做:
ghci> (fmap . const) 5 [1,2,3,4,5]
[5,5,5,5,5]
Run Code Online (Sandbox Code Playgroud)
但如果我尝试将子表达式提取(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)
Run Code Online (Sandbox Code Playgroud)
我认为这可能意味着GHC的类型推断在某种程度上失败了,但是当我向ghci询问subexpresiion的类型时,它没有问题:
ghci> :t (fmap . const)
(fmap . const) :: Functor f => b -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
那么这里发生了什么?有没有办法将这个子表达式提取到变量中?为什么不直截了当的let工作?
"什么是单态限制"可能是一个好的东西,在答案中链接(即:"另见......"),但这不是该问题的重复,除非StackOverflow已成为某种奇怪的版本游戏节目Jeopardy.当我问这个问题时,我已经知道单态性限制了,但对我来说,MR是导致我收到错误的原因一点也不明显.
在这方面,这个问题的答案没有帮助.它说"这意味着,在某些情况下,如果你的类型不明确......编译器将选择将该类型实例化为不模糊的东西",这与此处发生的情况几乎相反(MR正在产生歧义,不要删除它.)
这是可怕的单态限制.如果你运行:set -XNoMonomorphismRestriction它会工作.您也可以使用这样的显式类型签名来定义它
foo :: Functor f => b -> f a -> f b
foo = fmap . const
Run Code Online (Sandbox Code Playgroud)