我实现了一个搜索树内特定节点的函数。这是功能,它有效:
searchTree :: String -> Tree String -> Bool
searchTree value tree =
foldl (acc x -> if value `elem` x then True else acc) False (levels tree)
然后,我正在尝试实现相同的功能,但是这次,我想添加一个作家单元。这是不起作用的,编译器说"与实际类型'bool'"无法匹配预期类型的'writer [string] bool' ->错误是在第四行中,在说明'返回true'中。<<<<<<<<<<<</p>
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)
预先感谢。
您在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)
请注意,在这样的情况下,您(通常)确实想使用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
停止,在大多数情况下(包括作者单数)将(>>=)
关联到右侧的效率比左侧关联更有效,并且foldr
是兼容的使用GHC的列表融合,而foldl
不是。