我编写了一个在foldM中使用的函数f
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与您通常看到的a或b不同。元组的第一个和第二个元素不是同一类型(不,SValue不是String的类型同义词),而此签名暗示了该约束。另外,为什么在monad m上没有类约束?我在这里没有使用整个EvalMonad堆栈,但m至少应该是MonadError的一个实例。
发布于 2013-07-10 10:22:01
我使用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实际上与a或b相同;在类型中,任何以小写字母开头的标识符都是类型变量,并且在单个类型中多次重复这样的标识符表示相同的类型变量。
https://stackoverflow.com/questions/17561312
复制相似问题