奇怪的类型推理行为

时间:2016-03-13 15:54:36

标签: purescript

我试图了解为什么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

为什么它不想自动推断这种类型,即使它已经在功能签名中提供了?

1 个答案:

答案 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