高階関数クイズ

ちょっとした高階関数を使ったパズルです。前の会社の面接で使おうかなあと思っていたのですが、使う機会もなくなったので。全く別の機会に、高階関数を教えるための例を書いていて、遊んでいたら面白いものを見つけたので覚えていたのです。

# let twice f x = f (f x)

これは f という関数と値 x をもらって、f を二回 x に適用する関数です。

次の add1 は引数 x を受け取って、1足して返す関数です。これを twice に使うと、こうなります。

# let add1 x = x + 1
# add1 0
1
# twice add1 0
2

関数型言語に慣れている方なら、twice ((+) 1) 0 でも同じですね。(OCaml を使っていますが、慣れていない方の為に、出力を一部省略しています。# はプロンプトです。コメントじゃありません。あと、入力の後には ;; を入れてくださいね、、、頼みましたよ。)

さて、

# twice twice add1 0

は何を返すでしょうか。そうです。4 です:

# twice twice add1 0
4

これを続けるとこうなります。でも今は試さないでください。結果は本当です信用してくださって結構です:

# add1 0
1
# twice add1 0
2
# twice twice add1 0
4
# twice twice twice add1 0
16

さて、では、

# twice twice twice twice add1 0 

は何が帰って来ると思いますか?実際に試せばすぐですけど、まず頭で考えて みてください。それから実際に試してみてください。もしかすると、あなたの考えていた答えと違うかもしれません…

高階関数は便利ですけど、たまに、こういう不思議な例が出てきます。たまーにね、ごくたまーに。