関数の定義にパラメータ(仮引数)は必要なのか

「なんで関数の定義には引数のリストが必要なの?必要ないじゃない?」と聞かれて、なぜ必要なのかを説明しようとしたが、ふとHaskellだったらいらないんじゃないかと思ったので確認してみた。フィボナッチ数列を計算する関数を引数なしで実装する。

cond x y z = if x then y else z
dup f x = f x x
fib_ = dup(flip(flip.(.)(.).(flip (.).).((.subtract 1).).((dup.).(dup.((flip fib_.).(+))))).flip(cond.(0 ==)))
fib = (dup (fib_ 0 1))
main = print $ map fib [1..7]

はい。「部分適用の可能な条件分岐」と「関数fと引数xを与えるとfを引数xで呼び出した結果を引数xで呼び出す関数」の二つが与えられれば、フィボナッチ数列を求める関数の定義に引数リストは必要ないということがわかりました。きちんと調べもせずに「関数の定義を引数リストなしでできるはずがないじゃないか」なんて嘘を言ってはいけませんね。正しくは「世の中の大部分の言語では関数の定義には引数のリストが必須であり、また少なくともHaskellでは汎用的な部品が2つほど与えられれば引数のリストなしでフィボナッチ数列を求める関数を作ることができるが**決して読みやすくないのでおすすめできない**」となります。

読みやすく書くとこれくらい読みやすい。

fib2 1 = 1
fib2 2 = 1
fib2 n = fib2 (n - 1) + fib2 (n - 2)