デフォルト引数付きの関数型

badge

まず、デフォルト引数の使用例を見る。

f: (Int, Int, z := Int) -> Int
f(x, y, z := 0) = x + y + z

g: (Int, Int, z := Int, w := Int) -> Int
g(x, y, z := 0, w := 1) = x + y + z + w

fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int
fold(f, [], acc) = acc
fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0]))
assert fold(f, [1, 2, 3]) == 6
assert fold(g, [1, 2, 3]) == 8

:=以降の引数はデフォルト引数である。 部分型付け規則は以下の通り。

((X, y := Y) -> Z) <: (X -> Z)
((X, y := Y, ...) -> Z) <: ((X, ...) -> Z)

1番目は、デフォルト引数のある関数は、ない関数と同一視できる、という意味である。 2番目は、任意のデフォルト引数は省略できる、という意味である。

デフォルト引数の型は、引数を渡した場合と渡さなかった場合で変えることができる。 具体的には、if関数の型などが良い例である。

if: |T: Type, U: Type|(then: () -> T, else: () -> U := () -> NoneType) -> T or U

if関数は、else引数が与えられなければT or NoneTypeを返す。