Haskellで再帰関数のprintデバッグをしようとした時に、つまづいたのでメモとして残しておきたいと思います。
まず普通の再帰関数を書きます
Haskell
sum' :: Num p => [p] -> p
sum' [] = 0
sum' (x:xs) = x + sum' xs
よく考えたらsumってモノイド上なら定義できそうだから、もっと一般的には次のように書けそうです!
Haskell
msum :: Monoid p => [p] -> p
msum [] = mempty
msum (x:xs) = x <> msum xs
野生のプログラマがsumをInt->Int->Intみたいな型で書いてたら怒りましょう。
再帰関数でprintデバッグがしたい!
do構文を知らなかった頃は、sumの途中の値を知りたいと思い次のように書いていました。
Haskell
debug_sum [] = return 0
debug_sum (x:xs) = debug_sum xs >>= \x' -> print x' >> return (x+x')
main = debug_sum [1..5] >>= \x -> print x-- 0 5 9 12 14 15
「うわっ・・・私の再帰、分かりづらすぎ・・・?」
do構文
do構文を手にし、次のように書き直しました。
Haskell
debug_sum [] = return 0
debug_sum (x:xs) = do
x' <- debug_sum xs
print x'
return (x+x')
main = do
x <- debug_sum [1..5]
print x -- 0 5 9 12 14 15
「複数行に展開されてマシになったけど、読みやすいのかこれは...?」
結論
再帰のprintデバッグをわかりやすくしようと試行錯誤していたのですが、上記のコード以上に改良する方法がわからなくて困っています...
こっちのがわかりやすいよ!という書き方をご存知の有識者がいましたら教えてもらえれば幸いです。
ここまで読んでいただきありがとうございました!