我实现了一个搜索树内特定节点的函数。 这是功能,它的工作原理:
searchTree :: String -> Tree String -> Bool
searchTree value tree =
foldl (\acc x -> if value `elem` x then True else acc) False (levels tree)
然后,我正在尝试实现相同的功能,但这一次,我想添加一个Writer Monad。这个不起作用,编译器说“无法匹配预期类型'Writer [String] Bool'与实际类型'Bool'” - >错误发生在第4行,在'return True'指令中。
searchTree :: String -> Tree String -> Writer [String] Bool
searchTree value tree =
foldl (\acc x -> if value `elem` x then do
tell ["My logger message "]
return True else acc) return False (levels tree)
提前致谢。
答案 0 :(得分:4)
return False
周围缺少括号:
searchTree :: String -> Tree String -> Writer [String] Bool
searchTree value tree =
foldl (\acc x -> if value `elem` x then do
tell ["My logger message "]
return True else acc) (return False) (levels tree)
提示:为了使这些错误更容易找到,我总是删除我的硬编码类型签名,因为问题可能是我误解了类型。在这种情况下,删除类型签名会将错误更改为:
Couldn't match expected type `Bool' with actual type `m0 a0'
Expected type: a0 -> Bool
Actual type: a0 -> m0 a0
In the second argument of `foldl', namely `return'
In the expression:
foldl (\acc x -> if value `elem` x then do
tell ["My logger message "]
return True else acc) (return False) (levels tree)
答案 1 :(得分:1)
请注意,在这些情况下,您(通常)确实希望使用foldr
。
searchTree :: String -> Tree String -> Writer [String] Bool
searchTree value tree =
foldr (\x continue -> if value `elem` x then do
tell ["My logger message "]
return True else continue) (return False) (levels tree)
原因是,这不会检查整个列表,但是在第一个elem value x
处停止,在大多数情况下(包括作者monad)将(>>=)
与右侧关联比关联更有效在左侧,foldr
与GHC的列表融合兼容,而foldl
则不兼容。