推断的Haskell类型签名中的类型“t”是什么?

时间:2013-07-10 02:01:19

标签: haskell type-inference

我写了一个函数f,我在foldM

中使用了它
foldM (f xs) [] ids
...
f xs acc id = case lookup id xs of
    Just x -> return $ acc ++ [(id, x)]
    Nothing -> throwError $ TypeError "Cannot project nonexisting field"

我为它写的类型签名是:

[(String, Value)] -> [(String, Value)] -> String -> EvalMonad [(String, Value)]

然后我决定删除类型签名,因为该函数很简单,描述性很强。当我使用hdevtools获取推断类型时,我得到了

[(t, t)] -> [(t, t)] -> t -> m [(t, t)]
这是什么?我猜这个t与你常见的ab不同。元组的第一个和第二个元素不是相同的类型(不,SValue不是String的类型同义词),而此签名暗示该约束。另外,为什么monad m没有类约束?我这里没有使用整个EvalMonad堆栈,但m至少应该是MonadError的一个实例。

1 个答案:

答案 0 :(得分:2)

我使用ghci检查代码的推断类型,如下所示:

f typeError xs acc id = case lookup id xs of
    Just x -> return $ acc ++ [(id, x)]
    Nothing -> throwError $ typeError "Cannot project nonexisting field"

(请注意,我将固定的TypeError变为额外的参数typeError,因此我没有必要对其进行定义。

我得到的类型是:

f :: (Eq t, MonadError e m) =>
     ([Char] -> e) -> [(t, t1)] -> [(t, t1)] -> t -> m [(t, t1)]

所以我不确定为什么你会得到[(t, t)]类型的东西,或没有约束。类型签名中的t确实与ab相同;在类型中,任何以小写字母开头的标识符都是类型变量,单个类型中单个此类标识符的多次重复表示相同的类型变量。