参考記事
まず Arrow 記法で書く
{-# LANGUAGE Arrows #-} module FizzBuzz where import Control.Arrow ( (<<<), Arrow(arr) ) r :: String -> Bool -> String r s b = if b then s else "" fb :: Integer -> String fb = proc x -> do a <- (==0) . (`mod`3) -< x b <- (==0) . (`mod`5) -< x c <- r "Fizz" -< a d <- r "Buzz" -< b e <- arr (uncurry (++)) -< (c, d) f <- (=="") -< e g <- arr (uncurry r) -< (show x, f) arr (uncurry (++)) -< (g, e) main :: IO () main = mapM_ (putStrLn <<< fb) [1..40]
ここからワンライナーにしていく
a,b
は一箇所しか現れないので合体させる
&&&
と ***
を使う(並列的なアロー)
(&&&) :: a b c -> a b c' -> a b (c, c') infixr 3
(***) :: a b c -> a b' c' -> a (b, b') (c, c') infixr 3
fb = proc x -> do e <- arr (uncurry (++)) <<< r "Fizz".(==0).(`mod`3) &&& r "Buzz".(==0).(`mod`5) -< x g <- arr (uncurry r) <<< show *** (=="") -< (x, e) arr (uncurry (++)) -< (g, e)
ごにょごにょ
fb = proc x -> do e <- arr (uncurry (++)) <<< r "Fizz".(==0).(`mod`3) &&& r "Buzz".(==0).(`mod`5) -< x arr (uncurry (++)) <<< arr (uncurry r) *** id <<< (show *** (=="")) &&& snd -< (x, e)
うーん、ここがよく分からない。今日はここまでにしよう。