考慮下面這個簡單的BST定義:單子和自定義遍歷函數在Haskell
data Tree x = Empty | Leaf x | Node x (Tree x) (Tree x)
deriving (Show, Eq)
inOrder :: Tree x -> [x]
inOrder Empty = []
inOrder (Leaf x) = [x]
inOrder (Node root left right) = inOrder left ++ [root] ++ inOrder right
我想寫一個有序的功能,可以有副作用。我實現了與:
inOrderM :: (Show x, Monad m) => (x -> m a) -> Tree x -> m()
inOrderM f (Empty) = return()
inOrderM f (Leaf y) = f y >> return()
inOrderM f (Node root left right) = inOrderM f left >> f root >> inOrderM f right
-- print tree in order to stdout
inOrderM print tree
這工作得很好,但似乎重複的 - 同樣的邏輯已經存在於序我與Haskell的經驗使我相信,我可能做錯事,如果我我寫了兩次類似的東西。
有沒有什麼辦法可以編寫一個函數inOrder,它可以使用純函數或單函數?
這可能是有益的認識到,mapM_ f是隻是sequence_簡寫。地圖f - 也就是說,你*可以*使用普通的地圖向每個inOrder項目應用一個函數(a - > m b)。現在你有一個monadic動作列表,但它們沒有順序。函數sequence_接着將它們接受,並且將它們按順序應用於它們,從而給出按照列表順序進行單向操作的操作。當然,優化的神奇意味着這個列表很可能永遠不會被建立或一次完成! – MtnViewMark 2010-04-01 02:31:45
mapM是相似的,但使用序列,並且序列與sequence_相同,只是它收集結果,因爲它運行monadic操作並使該集合成爲複合操作的結果。 – MtnViewMark 2010-04-01 02:32:25