Haskellをかける少女

**※続編も書いたで！**
→[**Haskellをかけない中年**](https://qiita.com/jzmstrjp/items/e163affa4b2db48f9957)
→[**純粋関数型言語と参照透過性**](https://qiita.com/jzmstrjp/items/1de3c2b76b8a4dc2d30d)
→[**ワイのElmデビュー**](https://qiita.com/jzmstrjp/items/eb6fd45fe6324906a71a)

# とあるブラックなWeb制作会社にて
ワンマン社長「やめ太郎くん」

ワイ「はい」

ワンマン社長「明日から**インターン**の子が来るから、プログラミングを教えたってや」

ワイ「ええで」

ワンマン社長「まだ**中学生**やから、優しくしたってな？」

ワイ「お、おう」
ワイ「（**ファッ！？**）」
ワイ「（ちゅ、**中学生**て）」
ワイ「（うちの会社は**どんだけ人材に困ってんねん**・・・）」
ワイ「（青田買いにもほどがあるで・・・）」
ワイ「（ていうか**入社は何年後やねん**）」

# 翌日
少女「よろしくお願いします」

ワイ「おう、よろしくやで」
ワイ「（なんや、変わったTシャツ着とるな）」
ワイ「（**ハスケルカケル**、て書いてあるで）」
ワイ「（そんなん、**絶対Haskell書ける子やん**）」
ワイ「（ちょっと**ヤバい子**なんかな・・・）」
ワイ「きみ、名前はなんていうん？」

少女「**蓮　蹴子（はす・けるこ）**です」

ワイ「（**出たで**）」
ワイ「（**蹴る**に**子ども**で**けるこ**て）」
ワイ「（親は**何を願って名づけてんねん**）」
ワイ「え、**ええ名前やな**・・・」

少女「ありがとうございます」
少女「友達からは**ハスケル子**って呼ばれてます」

ワイ「（ただの**フルネーム**やないかい）」

# さっそく教えてみる
ワイ「ほな、今日はJavaScriptの勉強をしていくで〜」
ワイ「きみ、**JavaScript**は書いたことあるん？」

ハスケル子「**Java**は書いたことないです」
ハスケル子「ごめんなさい」

ワイ「ええでええで〜」
ワイ「（**まじか**）」
ワイ「ええねんけど、**Java**と**JavaScript**は全く別の言語やで」
ワイ「**メロンパン**と**メロンパンナちゃん**くらい違うんや」

ハスケル子「**どっちがメロンパンナちゃんですか**」

ワイ「・・・それは・・・**JavaScript**や（**震え声**）」
ワイ「（理由を聞かれる前に次の話題や・・・）」
ワイ「ほんで、プログラミング言語は何か勉強したことあるん？」

ハスケル子「**Haskell**を」

ワイ「（**せやろな**）」
ワイ「（これで**PHPだけです〜**言われたら**ずっこけるわ**）」
ワイ「おお〜、中学生にしてプログラミング経験者とは心強いで」
ワイ「ほなJavaScriptも余裕かもな〜」

# 作ってみたいものを聞いてみる
ワイ「ほな、何かJavaScriptで作ってみたいものとかある？」

ハスケル子「じゃあ・・・」
ハスケル子「初めてなので、まずは」
ハスケル子「**フィボナッチ数列**を表示するプログラムでも作ってみたいです」

ワイ「あー、ええな〜」
ワイ「その前にちょっと**トイレ行ってくるわ**」

# in トイレ
ワイ「なんや**フィナぼっち数列**て」
ワイ「**Google先生**に質問や・・・検索、と」

Google先生「もしかして：**フィボナッチ数列**」

ワイ「おお、フィナ**ぼっち**やなくてフィボ**ナッチ**か」
ワイ「学生時代ずっと**ぼっち**やったから、それに引っぱられてもうたわ」

ワイ「なになに」
ワイ「0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610・・・っていう数列か」
ワイ「どういう規則性や」
ワイ「ふむふむ」
ワイ「**0番目の数字**と**1番目の数字**を足したものが**2番目の数字**になって」
ワイ「**1番目の数字**と**2番目の数字**を足したものが**3番目の数字**になって」
ワイ「**2番目の数字**と**3番目の数字**を足したものが**4番目の数字**になって・・・」
ワイ「ああ、なんか見たことあるわ」
ワイ「これがフィナぼっち、いや**フィボナッチ数列**いうやつなんか」

# 研修開始
ワイ「お待たせやで〜」
ワイ「よーし、ほなまずはワイがJavaScriptのお手本を見せていくで〜」

```javascript:yametaro.js
const fibo = n => {
  // ここに処理内容を書く。
};

fibo(10);
```

ワイ「こんな感じで、`fibo(10)`って実行したら10番目のフィボナッチ数が返ってくるような**関数**を作っていくで〜」

ハスケル子「はい」

ワイ「**n**ってのは**引数**や」
ワイ「`fibo(10)`って実行したなら、**n**には**10**が入ってくんねや」

ワイ「ほな、**関数fiboの中身を書いていくで**」
ワイ「まず、フィボナッチ数列の**0番目の数は0**」
ワイ「あと、**1番目の数は1**」
ワイ「ってことは決まっとるから」
ワイ「ここはベタ書きや」

```javascript:yametaro.js
  const arr = [0, 1];
```

ワイ「こんな感じでフィボナッチ数列を**配列**にしていってみるで」

ワイ「ほんで、**2番目以降**のフィボナッチ数は」
ワイ「その**前の数字**と**前の前の数字**を**足したもの**を入れてかなあかん、と」
ワイ「ほな、**2**から**n**まで**for文**で繰り返しながら、どんどん**継ぎ足し継ぎ足し**でフィボナッチ数列を作っていけばええわけやから・・・」

```javascript:yametaro.js
  // 2からnまでfor文で繰り返す。
  for (let i = 2; i <= n; i++) {
    // 配列に継ぎ足すのは、
    // 1つ前の数値と2つ前の数値を足したもの。
    arr.push(arr[i - 1] + arr[i - 2]);
  }
```

ワイ「こうやな」
ワイ「ほんで最後に、配列の**n番目の要素**を**return**すればええねや」

```javascript:yametaro.js
  return arr[n];
```

ワイ「できたで」

```javascript:yametaro.js
const fibo = n => {
  const arr = [0, 1];

  // 2からnまでfor文で繰り返す。
  for (let i = 2; i <= n; i++) {
    // 配列に継ぎ足すのは、
    // 1つ前の数値と2つ前の数値を足したもの。
    arr.push(arr[i - 1] + arr[i - 2]);
  }

  return arr[n];
};
```

# どや？
ワイ「な、簡単やろ？」

ハスケル子「**全然わかりません**」

ワイ「**！？**」
ワイ「え・・・何で・・・」

ハスケル子「**Haskell**には**for文ないので**・・・・」

ワイ「（**まじか**）」
ワイ「あー、せやったなー」
ワイ「（**知らんけど**）」

ハスケル子「あと**Haskell**では**配列[^1]もイミュータブル（不変）**なので、」
ハスケル子「同じ配列に**どんどん要素を足していく**、みたいのも**できない**ので」

ワイ「あー、せやったなー」
ワイ「（**ぐぬぬぬぬ**）」

ハスケル子「むしろ、**私ならこうするなー**ってのはあります」

ワイ「お、おう」
ワイ「（もう**先輩にダメ出しかいな**）」
ワイ「（しまいにゃ**しばくど**）」
ワイ「ど、どんな感じか教えてや♪」

ハスケル子「はい」

```javascript:keruko.js
const fibo = n => (n === 0 || n === 1)? n: fibo(n - 1) + fibo(n - 2);
```
ハスケル子「こんな感じです」

ワイ「なるほど、こう来はりましたか〜」
ワイ「（**なんやこれ**）」
ワイ「（**たったの1行やん・・・！！！**）」

```javascript:keruko.js
(n === 0 || n === 1)? n
```

ハスケル子「この部分は」
ハスケル子「**n**が**0か1**なら**nをそのまま返す**ってことです」

ワイ「せやな」

ハスケル子「nが**2以上**の場合は・・・」

```javascript:keruko.js
fibo(n - 1) + fibo(n - 2)
```

ハスケル子「こっちを返します」
ハスケル子「つまり・・・」
ハスケル子「**数学の神に問うんです**」

ワイ「**せやな**」
ワイ「（分かってへんことがバレんようにここは同意や・・・）」
ワイ「**神に問うんや！**」

ハスケル子「たとえば、**10番目のフィボナッチ数は何ですか？**って**神に問うんです**」
ハスケル子「そうすると」

> **汝、10番目のフィボナッチ数を求めるか・・・**
> **ならば、9番目と8番目のフィボナッチ数を足すがよい・・・**

ハスケル子「って**神がお答えになるんです**」
ハスケル子「だから次は**こう問うんです**」
ハスケル子「その**9番目と8番目のフィボナッチ数は何と何ですか？**って」
ハスケル子「そうすると」

> **汝、9番目と8番目のフィボナッチ数を求めるか・・・**
> **9番目のフィボナッチ数は、8番目と7番目のフィボナッチ数を足すがよい・・・**
> **また、8番目のフィボナッチ数は、7番目と6番目のフィボナッチ数を足すがよい・・・**

ハスケル子「って**神はお答えになるんです**」
ハスケル子「フィボナッチ数って**そういうものなんです**」
ハスケル子「それを**そのままコードに書けば良いんです**」

ハスケル子「つまり、**n番目のフィボナッチ数**を求めるなら、」
ハスケル子「**n-1番目**のフィボナッチ数と、**n-2番目**のフィボナッチ数を足せば良いんです」

ハスケル子「だから**こうです**」

```javascript:keruko.js
fibo(n - 1) + fibo(n - 2)
```

ハスケル子「あるフィボナッチ数を求めるために、**別のフィボナッチ数を求めるんです**」
ハスケル子「**関数fibo**の中で**関数fibo**を使うことで、**関数fibo**は完成するんです」

ワイ「そ、そんなことしたら**無限ループ**になるかもしれんやん？」

ハスケル子「**なりません**」
ハスケル子「最終的には**関数fibo自身を使わずに0や1を返す**部分にたどり着くことになるので」
ハスケル子「そこでちゃんと終わります」

ワイ「（**ぐぬぬぬぬぬ・・・！！！**）」

ワイ「**ご、合格や！！！**」

ワンマン社長「（何が合格や・・・）」
ワンマン社長「（**苦しすぎる**で・・・）」

ワイ「（アカン、**関数fibo**の**ゲシュタルト崩壊**で頭が**パニック**や）」
ワイ「初日やから、この辺で終わりでええで〜」

ワンマン社長「（あ、**逃げた**・・・）」

# こんな子どこで見つけたんや
ワイ「**蓮　蹴子**さんハンパないなぁ・・・」
ワイ「**for文**で**i**をインクリメントしながら数列を継ぎ足して作っていくんやなくて、**定義をそのままコードとして書く**んやな・・・」
ワイ「カッコ良すぎるわ・・・」
ワイ「問題の本質を見抜き、初めて触る言語でサクッと実装する・・・」
ワイ「なんて**中学生**や・・・」
ワイ「社長・・・**こんな逸材どこで！？**」

ワンマン社長「（人差し指を立てて）**ツイッタ〜！**」

ワイ「**ビズリーチ**ちゃうんかい！！！」

**〜Fin〜**

# 追記
続編もよろしくやで！

+ [**Haskellをかけない中年**](https://qiita.com/jzmstrjp/items/e163affa4b2db48f9957)
+ [**純粋関数型言語と参照透過性**](https://qiita.com/jzmstrjp/items/1de3c2b76b8a4dc2d30d)
+ [**ワイのElmデビュー**](https://qiita.com/jzmstrjp/items/eb6fd45fe6324906a71a)


[^1]: 正しくは**リスト**ですね。