次の単純なBST定義があるとします。
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
これは問題なく動作しますが、繰り返しのようです。同じロジックがinOrderにすでに存在し、Haskellでの経験から、同じようなことを2回書いていると、おそらく何か間違ったことをしていると思います。
純粋な関数または単調な関数のいずれかを取ることができる単一の関数inOrderを作成する方法はありますか?