LoginSignup
10

More than 5 years have passed since last update.

HaskellでFizzBuzz

Posted at

Haskellを勉強中で無性に、腐るほどあるFizzBuzz(関数)が書きたくなった。

fizzbuzz :: Integer -> [String] 
fizzbuzz 0 = []
fizzbuzz n
    | n `mod` 15 == 0 = fizzbuzz(n - 1) ++ ["fizzbuzz"]
    | n `mod` 3 == 0 = fizzbuzz(n - 1) ++ ["fizz"]
    | n `mod` 5 == 0 = fizzbuzz(n - 1) ++ ["buzz"]
fizzbuzz n = fizzbuzz(n - 1) ++ [show n]

間違っているかもしれない解説

fizzbuzz :: Integer -> [String] 

はfizzbuzz関数の型宣言。これはInteger型を引数にしてStringの配列を返すという意味。これは書かなくても推論してくれるらしいがすごいH本によると書いたほうがいいらしい。

fizzbuzz 0 = []

fizzbuzz 0が来たら、

fizzbuzz n
    | n `mod` 15 == 0 = fizzbuzz(n - 1) ++ ["fizzbuzz"]
    | n `mod` 3 == 0 = fizzbuzz(n - 1) ++ ["fizz"]
    | n `mod` 5 == 0 = fizzbuzz(n - 1) ++ ["buzz"]

は15か3か5で割れるかのガードで

fizzbuzz n = fizzbuzz(n - 1) ++ [show n]

はこぼれたやつ。

この関数は再帰的に呼ばれるので、例えばfizzbuzz 3とすると、
fizzbuzz 3 -> fizzbuzz(2) ++ ["fizz"] -> fizzbuzz(1) ++ ["2", "fizz"] -> fizzbuzz(0) ++ ["1", "2", "fizz"]->["1", "2", "fizz"]
となる(はず)。

呼ばれる順に詳しく見ていく

fizzbuzz n
    | n `mod` 15 == 0 = fizzbuzz(n - 1) ++ ["fizzbuzz"]
    | n `mod` 3 == 0 = fizzbuzz(n - 1) ++ ["fizz"]
    | n `mod` 5 == 0 = fizzbuzz(n - 1) ++ ["buzz"]

はガードと呼ばれるもので、nがなんの倍数か判定している。それがわかったらfizzbuzz(n -1)と対応する文字列をくっつけて返す。"fizzbuzz" : fizzbuzz(n - 1)としたくなるが(自分だけ?)、これだと結果が逆になってしまう。

fizzbuzz n = fizzbuzz(n - 1) ++ [show n]

は上のガードからこぼれたら来るもので、こちらはshow nInteger -> Stringしている。

fizzbuzz 0 = []

は最後なので空の配列を返して終了

fizzbuzz 100

*Main> fizzbuzz 100
["1","2","fizz","4","buzz","fizz","7","8","fizz","buzz","11","fizz","13","14","fizzbuzz","16","17","fizz","19","buzz","fizz","22","23","fizz","buzz","26","fizz","28","29","fizzbuzz","31","32","fizz","34","buzz","fizz","37","38","fizz","buzz","41","fizz","43","44","fizzbuzz","46","47","fizz","49","buzz","fizz","52","53","fizz","buzz","56","fizz","58","59","fizzbuzz","61","62","fizz","64","buzz","fizz","67","68","fizz","buzz","71","fizz","73","74","fizzbuzz","76","77","fizz","79","buzz","fizz","82","83","fizz","buzz","86","fizz","88","89","fizzbuzz","91","92","fizz","94","buzz","fizz","97","98","fizz","buzz"]

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10