Skip to content

Commit

Permalink
Complete example of fib
Browse files Browse the repository at this point in the history
  • Loading branch information
igrep authored Mar 24, 2024
1 parent 0b0f873 commit 03d55e0
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions assets/18.md
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,6 @@ doubles (x : xsLeft) = x * 2 : doubles xsLeft

![`doubles`関数がどのように書き換えられたか](./18-pattern-matching.png)

hoge: 画像を編集してそれらしく

`->`の代わりに`=`でパターンとその定義を区切っている点と、`(x : xsLeft)`のように、パターン全体を**カッコで囲う**必要がある点にご注意ください。

カッコで囲う必要があるのは、`case`式と異なり関数定義では複数の引数を扱うことがあるためです。例えば`doubles`関数に引数を増やして、2以外の、引数で指定した任意の数を掛けられる関数、`times`関数を定義してみたとします。関数定義で引数を直接パターンマッチしたい場合、次のように`x : xsLeft`をカッコで囲わなければなりません:
Expand All @@ -801,29 +799,31 @@ ghci| :}
<interactive>:47:1: error: Parse error in pattern: times
```

`times n x : xsLeft = ...`と書いた場合、`n``x``:``xsLeft`という4つの引数を受け取るように見えたり
`times n x : xsLeft = ...`と書いた場合、あたかも`(n x) : xsLeft`という一塊でパターンマッチングしているかのように見えるなど(実際にはそのようなパターンマッチングはできませんが)、うまく解釈できない構文になってしまうからです。書き換えの際はご注意ください。

おまけにかっこいい例: よく見かける(*でもすごく効率が悪い*`n`番目のフィボナッチ数を計算する関数
それからおまけに、関数の引数でのパターンマッチを利用した、もっとかっこいい例を紹介しましょう。Haskellについて紹介する際によく用いられる例なので、よそでも見たことがあるかも知れません。引数として整数を受け取って、その整数番目のフィボナッチ数を計算する関数です。まずは普通の`case`式を利用した書き方から:

```
```haskell
fib n =
case n of
0 -> 0
1 -> 1
_ -> fib (n - 2) + fib (n - 1)
```

`case`で書くと↑のなのを、
引数`n`に対して`case`式でパターンマッチングすることで、`n``0``1`であればそのまま`0``1`を返し、それ以外の数であれば(フィボナッチ数の定義通り)二つ前のフィボナッチ数と一つ前のフィボナッチ数を足して返します。

```
これを、`case`式の代わりに関数の引数におけるパターンマッチで書き換えると...

```haskell
fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
```

と書き換えることができる。
[元々のフィボナッチ数の定義][3]っぽくてかっこいい!
(でもいずれにしても効率はすごく悪いのでくれぐれも使わないこと)
このように、[フィボナッチ数の漸化式を用いた定義][3]とそっくりな見た目になります。かっこいい!

ただ、`case`式を使ったバージョンであれ引数でのパターンマッチングを使ったバージョンであれ、いずれにしても効率はすごく悪いのでくれぐれも実際に使わないようご注意ください。Haskellでフィボナッチ数を計算するより効率の良い方法は検索すればたくさんヒットするでしょう。

[3]: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0#%E6%A6%82%E8%A6%81

Expand Down

0 comments on commit 03d55e0

Please sign in to comment.