在foldl函数Haskell中添加Writer Monad
我实现了一个在树中搜索特定节点的函数。 下面是函数,它可以工作:在foldl函数Haskell中添加Writer Monad,haskell,Haskell,我实现了一个在树中搜索特定节点的函数。 下面是函数,它可以工作: searchTree :: String -> Tree String -> Bool searchTree value tree = foldl (\acc x -> if value `elem` x then True else acc) False (levels tree) 然后,我试图实现相同的功能,但这次,我想添加一个Writer Monad。这一个不起作用,编译器说“无法将预期类型‘W
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’匹配->错误在指令‘return True’的第4行
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)
提前感谢。您缺少
返回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)
提示:为了更容易发现这些bug,我总是删除硬编码的类型签名,因为问题可能是我对类型有误解。在这种情况下,删除类型签名将错误更改为:
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)
您缺少
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)
提示:为了更容易发现这些bug,我总是删除硬编码的类型签名,因为问题可能是我对类型有误解。在这种情况下,删除类型签名将错误更改为:
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)
原因是,这不会检查整个列表,而是在第一个
元素值x
处停止,在大多数情况下(包括writer monad),将(>>=)
关联到右侧比关联到左侧更有效,而foldr
与GHC的列表融合兼容,而foldl
则不兼容。请注意,在这种情况下,您(通常)确实希望使用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)
原因是,这不会检查整个列表,而是在第一个
元素值x
处停止,在大多数情况下(包括writer monad),将(>>=)
关联到右侧比关联到左侧更有效,而foldr
与GHC的列表融合兼容,而foldl
则不兼容。为了清楚起见,我应该补充一点,即在修复显式类型签名后,最好将其放回原处。为了清楚起见,我应该补充一点,即在修复后,最好将显式类型签名放回原处。