FizzBuzzをArrowで

書いてみた。もっとカッコ良く書けると思うんだけど。ArrowChoiceとか使って。

import Control.Arrow

newtype FB a b = FB {run :: a -> b}

instance Arrow FB where
    arr f             = FB f
    (FB f) >>> (FB g) = FB (g . f)
    first (FB f)      = FB (first f)

fizzbuzz = map (uncurry f . run fizzbuzz') [1..100]
  where fizzbuzz' = (arr id) &&& (fizz &&& buzz)
        fizz = FB $ \x -> if (x `mod` 3) == 0 then "Fizz" else ""
        buzz = FB $ \x -> if (x `mod` 5) == 0 then "Buzz" else ""
        f x ("", "") = show x
        f x (y, "")  = y
        f x ("", z)  = z
        f x (y, z)   = y ++ z