在haskell中为do表示法分配元组时发生类型错误

时间:2018-10-21 11:58:59

标签: haskell

这是我拥有的haskell代码:

myFold:: ([a] -> (b, [a])) -> [a] -> [b]
myFold fn []  = []
myFold fn lst = do
    (ast, newLst) <- (fn lst)
    myFold fn newLst ++ [ast]

我认为每个认识haskell的人都会得到我想做的事情。但是这段代码是错误的,我真的不明白为什么。编译器抱怨(ast, newLst) <- (fn lst)行中的类型不匹配,我看不到出什么问题了。有人可以指出语法必须是什么吗?我也很确定有更好的方法可以做到这一点,所以请随时提供替代方法。

1 个答案:

答案 0 :(得分:1)

简短答案:停止使用do表示法。它没有按照您的想法做。

长答案:

do-符号在这里被滥用。我不会在这里做完整的monad教程,但将逐行向您展示您应该做的事情。

首先,第myFold fn lst = do行是错误的,因为您不应该使用do表示法,所以我们将其删除:

myFold fn lst =

第二,行(ast, newLst) <- (fn lst)滥用了do表示法中的构造,即箭头。实际上,您实际上想要的是一个简单的旧let语句,因此请替换掉它,并指出稍后我们还需要一个随附的in

    let (ast, newLst) = fn lst

第三,当您表示要返回的值时,您需要一个in

    in myFold fn newLst ++ [ast]

总而言之:

myFold fn lst =
    let (ast, newLst) = fn lst
    in myFold fn newLst ++ [ast]

如果您想了解如何正确{em> 使用do表示法,前提是您了解Monads,则可以在线获得plenty of tutorials。我不会在此进行解释,因为这完全超出了此代码中核心问题的范围。