• 11
いいね
• 1
コメント
に投稿
この記事は最終更新日から1年以上が経過しています。

```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 n``Integer -> 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"]
```