Haskellでもデバッグプリントしたい + Sコンビネータの練習
いきなりですが、やっぱりHaskellでもデバッグプリントしたいですよね。調べた結果、Debug.Traceにある関数traceを使えばできることがわかりました。おお、副作用が… 実装はきっと暗黒面なんだろうな(キレイな身体じゃ生きられない、みたいな)。
そのまま使ってもいいんですが、せっかくなんでRubyっぽく関数pを定義してみました。
ファイル: a.hs
module Main (main) where import Debug.Trace (trace) p :: (Show a) => a -> a p = p' "" p' :: (Show a) => String -> a -> a p' s a = trace (s ++ show a) a inc :: Int -> Int inc i = i + 1 main :: IO () main = print $ p $ inc 10
実行例:
$ runghc a.hs 11 ← デバッグプリントの出力。 11 ← printの出力。
ついでに。上のプログラムでは関数p'のとこで変数aを2回参照しています。Sコンビネータを使ったら簡単になるかなと思ってちょっと試してみました。以下、Sコンビネータに至るまでの手順です。
p' :: (Show a) => String -> a -> a -- p' s a = trace (s ++ show a) a -- (1) -- p' s a = flip trace a (s ++ show a) -- (2) -- p' s a = (flip trace) a $ ((++) s . show) a -- (3) -- p' s a = starling (flip trace) ((++) s . show) a -- (4) p' s = starling (flip trace) ((++) s . show) -- (5) where starling :: (a -> b -> c) -> (a -> b) -> a -> c starling f g x = f x (g x)
(1)オリジナル。(2)traceの引数の順番を入れ換える。(3)flipの辺でカリー化を意識する。showの辺を関数合成にする。(4)Sコンビネータを適用する。(5)変数aは不要なので消す。
うーむ。やっぱ(1)のままでいいや。(5)は読めません。