奇怪的类型推断行为
Strange type inference behavior
我试图理解为什么 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
为什么它不想自动推断这种类型,即使它已经在函数签名中提供了?
当前的编译器无法对函数依赖建模,Haskell 和 mtl
库使用函数依赖来捕获 MonadState
中两个类型参数之间的关系。
这意味着编译器无法确定两个状态类型必须相同(也就是说,如果我们为 StateT (Maybe Int) Identity
找到 MonadState
的实例,则状态类型被强制为 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
我试图理解为什么 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
为什么它不想自动推断这种类型,即使它已经在函数签名中提供了?
当前的编译器无法对函数依赖建模,Haskell 和 mtl
库使用函数依赖来捕获 MonadState
中两个类型参数之间的关系。
这意味着编译器无法确定两个状态类型必须相同(也就是说,如果我们为 StateT (Maybe Int) Identity
找到 MonadState
的实例,则状态类型被强制为 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