fizzbuzz in Haskell

Haskellだいぶ慣れてきた。

-- fizzbuzz.hs
fizzbuzz n
    | n `mod` 15 == 0 = "fizzbuzz"
    | n `mod` 5 == 0  = "buzz"
    | n `mod` 3 == 0  = "fizz"
    | otherwise       = show n

main = mapM_ (putStrLn . fizzbuzz) [1..]
$ runghc fizzbuzz.hs
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
...

mapが一般の関数を適用するのに対し、mapMMonadを返す関数を適用し、その結果のリストを値に持つMonadを返す。 mapM_mapMとほぼ同じだが、値が空のMonadを返す。

map :: (a -> b) -> [a] -> [b]
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()

putStrLn . fizzbuzzは関数合成で、1引数関数のfizzbuzzに対して\x -> putStrLn (fizzbuzz x)と同じ意味になる。仮にfizzbuzzが2引数関数であれば、\x y -> putStrLn (fizzbuzz x y)と同じ意味になる。