我试图了解为什么purescript
无法在此简单代码中正确推断map
参数的类型:
maybeInc :: String -> StateT (Maybe Int) Identity Unit
maybeInc "a" = modify $ map (1 +)
maybeInc _ = return unit
这是我的错误消息:
No type class instance was found for Control.Monad.State.Class.MonadState (_0 Int) (StateT (Maybe Int) Identity) The instance head contains unknown type variables. Consider adding a type annotation.
但是,如果我手动指定类型,它会起作用:
maybeInc "a" = modify $ \(m :: Maybe Int) -> map (1 +) m
为什么它不想自动推断这种类型,即使它已经在功能签名中提供了?
答案 0 :(得分:2)
当前的编译器无法建模函数依赖关系,Haskell和mtl
库中使用它来捕获MonadState
中两个类型参数之间的关系。
这意味着编译器无法确定两种状态类型必须相同(即,如果我们为MonadState
找到StateT (Maybe Int) Identity
的实例,则状态类型被迫是Maybe Int
)。
目前,一种解决方案是添加类型注释:
maybeInc :: String -> StateT (Maybe Int) Identity Unit
maybeInc "a" = modify modifier
where
modifier :: Maybe Int -> Maybe Int
modifier = map (1 +)
maybeInc _ = return unit