本当にこれが実現できるかどうかは極めて怪しい。
// range関数を多重定義で定義
let range =
(stop: number) -> range(0, stop)
(start: number, stop: number) -> ...
// 変数xに、`[0, 1, 2, 3, 4, 5]`か「stop引数を受け取って配列を返す関数」の「どちらとしても解釈可能な値」を代入
let x = range(5)
// `[1, 2, 3, 4, 5, 6]`の値を生成
// 変数xの値を配列と解釈して処理
let list1 = x |> map(num -> num + 1)
// `[ [5, 6], [5, 6, 7, 8] ]`の値を生成
// 変数xの値を「stop引数を受け取って配列を返す関数」と解釈して処理
let list2 = [6, 8] |> map(x)
// 変数xの値をコンソールに表示する。print関数は配列も関数も受け付ける。
// …この場合のxの値は何!?
print(x)
引数の数が同じ多重定義のみ可能とすれば、カリー化と多重定義の両立が可能かもしれない。関数のUnion型として表現できる。
let multi =
(a: number, b: number) -> a * b
(str: string, count: number) -> str.repeat(count)
(count: number, str: string) -> multi(str, count)
// このdoubleの型は`(number -> number) | (string -> string)`
let double = multi(2)
// 値は`4`
print(double(2))
// 値は`"ベベ"`
print(double("ベ"))
// 値はおそらく`( (b: number): number -> a * b ) | ( (str: string): string -> multi(str, count) )`
print(double)