こんにちは、やきつかと申す者です。
Haskellで再帰関数のprintデバッグをしようとした時に、つまづいたのでメモとして残しておきたいと思います。
#普通の再帰関数
sum' :: Num p => [p] -> p
sum' [] = 0
sum' (x:xs) = x + sum' xs
これができなきゃ何も始まらないよ!
よく考えたらsumってモノイド上なら定義できそうだから、もっと一般的には次のように書けるはずだ!
msum :: Monoid p => [p] -> p
msum [] = mempty
msum (x:xs) = x <> msum xs
野生のプログラマがsumをInt->Int->Intみたいな型で書いてたら「そんな汎用性の無い関数で書いてるの?そんなんじゃダメだよ~」とイキりちらかしましょう。
ちなみに僕はPreludeのsumを使うんですけどね。
#再帰関数でprintデバッグがしたい!
##do構文は僕を置き去りにした
do構文を知らなかった若かりし僕は、sumの途中の値を知りたいと思い次のように書いていました。
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構文、GETだぜ!
do構文を手にし、最強になった僕は次のように書き直しました。
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
ちょっと前の自分「ん...?複数行に展開されてマシになったけど、読みやすいのかこれは...?」
#結論
本当にすみませんでした。Qiitaでの初めての記事だったので、ノリノリになりすぎてしまいました...
再帰のprintデバッグをわかりやすくしようと試行錯誤していたのですが、上記のコード以上に改良する方法がわからなくて困っています...
こっちのがわかりやすいよ!という書き方をご存知の有識者がいましたら教えてもらえれば幸いです。
ここまで読んでいただきありがとうございました!