今日の昼ごはん(高階関数クイズの解答)

問題編はこちら。まだ解いていない人はこちらを先にみてください。高階関数クイズ - Oh, you `re no (fun _ → more)

ネタバレ防止に

1

2

4

8

16

32

64

さすがに関数適用が左結合性なあたりは十分承知しているので2 * nになるわけがないじゃん、というところまではすぐわかったのだが、落とし穴を飛び越えた着地先にもう一つ落とし穴があっておもいっきりはまってしまった。
twiceをt, 引数の関数をn回適用する関数をと書くことにすると

t = <2>
t t = <2> <2> = <2 ** 2> 
-- これがたまたま同じ2同士の演算なので勘違いしやすい。
-- あと<2 * 2>という解釈もできてしまう罠
t t t = (t t) t = <4> <2> = <2 ** 4> = <16>
-- <4 * 2>だと思った人はここでぶつかる。
-- これを<4 ** 2>だと思い込むと二つめの罠
t t t t = (t t t) t = <16> <2> = <2 ** 16> = <65536>
-- <16 ** 2>だと勘違いすると256と答えてしまう。

うん、まあ、あっさりと256って答えて落とし穴にはまった。

罠は2つ重なっているわけだ。まず関数適用の結合順序をぼんやりとしか考えていない人は(t t t t)を(t (t t t))だと勘違いする、と。数値で言うなら(2 *)と見せかけて(2 **)な罠。twiceって名前から間違った連想をしてしまいがち。しかも 2 * 1 == 2 ** 1, 2 * 2 = 2 ** 2 だから最初の2つはその解釈でも成立してしまう。ちゃんと問題文を見ていれば(t t t)が<8>にならないところで正されるはず。次に(** 2)と(2 **)が2と4に関してイコールなのが罠。2 ** 2 = 2 ** 2, 2 * 4 == 2 ** 4が成り立つので正解は 2 ** 16 なのに 16 ** 2 と答えてしまう。これもちゃんと問題文を見ていれば2 ** 1 /= 1 ** 2 だからわかったはずなんだけどな…。