Gleamの関数は第一級の値です。つまり、関数はふつうの値と同じように、変数に代入したり、引数として渡したり、ほかの関数から返したりできます。
モジュールで定義した名前付きの関数は、その名前で参照できます。
pub fn main() {
// Assign the function to a variable
let f = add_one
// Invoke the function
f(1) // -> 2
f(2) // -> 3
}
fn add_one(x) {
x + 1
}
Gleamには無名関数もあり、これはほかの関数の中で定義します。
// Define the function
let f = fn(x) { x + 1 }
// Invoke the function
f(1) // -> 2
f(2) // -> 3
関数の型は、無名関数とよく似た構文で書きます。IntとFloatを受け取ってIntを返す関数の型は、次のように書きます。
fn(Int, Float) -> Int
無名関数は、定義された時点でスコープにあった変数を参照できます。このような関数を_クロージャ_と呼びます。
let secret_number = 42
// This function always returns 42
fn() { secret_number }
_関数キャプチャ_構文を使うと、1つの引数を関数に渡す無名関数を手軽に作れます。次の2つの式は同じ意味です。
// Anonymous function syntax
let f = fn(x) { my_function(1, 2, x) }
// Function capture syntax
let f = my_function(1, 2, _)
この演習では、データに変換を加えることで動作する暗号化デバイスのソフトウェアを書くことになりました。より単純な関数を組み合わせて、複雑な関数を柔軟に作れる方法が必要です。
それぞれのタスクでは、呼び出し元のスコープから呼び出せる匿名関数を返してください。
secret_addを実装しましょう。これは1つの引数を受け取り、その引数にsecret_addに渡された引数を足す関数を返します。
let adder = secret_add(2)
adder(2)
// -> 4
secret_subtractを実装しましょう。これは1つの引数を受け取り、その引数からsecret_subtractに渡された秘密の値を引く関数を返します。
let subtractor = secret_subtract(2)
subtractor(3)
// -> 1
secret_multiplyを実装しましょう。これは1つの引数を受け取り、その引数にsecret_multiplyに渡された秘密の値を掛ける関数を返します。
let multiplier = secret_multiply(7)
multiplier(3)
// -> 21
secret_divideを実装しましょう。これは1つの引数を受け取り、その引数をsecret_divideに渡された秘密の値で割る関数を返します。
let divider = secret_divide(3)
divider(32)
// -> 10
secret_combineを実装しましょう。これは1つの引数を受け取り、その引数に、secret_combineに渡された2つの関数を順番に適用する関数を返します。
let multiply = secret_multiply(7)
let divide = secret_divide(3)
let combined = secret_combine(multiply, divide)
combined(6)
// -> 14