推断的Haskell类型签名中的类型“t”是什么?
我写了一个函数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不同于通常看到的通常的a
或b
。 元组的第一个元素和第二个元素不是相同的类型(不,SValue不是字符串类型的同义词),而此签名意味着该约束。 另外,monad m为什么没有类限制? 我没有在这里使用整个EvalMonad堆栈,但m
至少应该是MonadError
一个实例。
我使用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
相同; 在一个类型中,以小写字母开头的任何标识符都是一个类型变量,并且单个类型中的单个这样的标识符的多次重复代表相同的类型变量。
上一篇: What is a type "t" in an inferred Haskell type signature?