2013-07-10 108 views
1

我写了一个函数f,我在一个foldM使用:推断的Haskell类型签名中的类型“t”是什么?

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不是字符串类型的同义词),而此签名意味着该约束。另外,monad m为什么没有类限制?我在这里没有使用整个EvalMonad堆栈,但m至少应该是MonadError的一个实例。

+0

我想你在复制/粘贴该类型时放弃了一个约束。你应该得到'Monad m => [(t,t)] - > [(t,t)] - > t - > m [(t,t)]'的类型。差异是相当重要的。 –

+0

nope,这是hdevtools打印的。我认为,最终ghci必须把事情做好,否则我会得到段错误或类似的错误,但我想知道为什么错误。 AFAIK,hdevtools和ghc-mod是人们用于类型推断的。这是非常有用的,但当我分析一个不平凡的表达时,我不能让它脱落...... – BruceBerry

+0

看起来像这是[this ghc-mod bug](https://github.com/kazu-yamamoto/ghc -mod /问题/ 69)。 –

回答

3

我用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相同;在一个类型中,以小写字母开头的任何标识符都是一个类型变量,并且单个类型中的单个这样的标识符的多次重复代表相同的类型变量。

+0

我很高兴至少ghc得到它的权利:-)所以这是一个在hdevtools中的错误? – BruceBerry

+0

这是我的印象,是的。 –