这是我拥有的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)
行中的类型不匹配,我看不到出什么问题了。有人可以指出语法必须是什么吗?我也很确定有更好的方法可以做到这一点,所以请随时提供替代方法。
答案 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。我不会在此进行解释,因为这完全超出了此代码中核心问题的范围。