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 }
_函数捕获_语法提供了一种便捷的简写方式,用来创建把单个实参传递给某个函数的匿名函数。下面两个表达式是等价的:
// Anonymous function syntax
let f = fn(x) { my_function(1, 2, x) }
// Function capture syntax
let f = my_function(1, 2, _)
在这个练习中,你的任务是为一台加密设备编写软件,它通过对数据执行变换来工作。你需要一种方法,把简单的函数组合起来,灵活地创建复杂的函数。
对于每个任务,返回一个可以从调用方作用域中调用的匿名函数。
实现 secret_add。它应该返回一个函数,这个函数接受一个实参,并把传给 secret_add 的实参加到它上面。
let adder = secret_add(2)
adder(2)
// -> 4
实现 secret_subtract。它应该返回一个函数,这个函数接受一个实参,并从该实参中减去传给 secret_subtract 的秘密值。
let subtractor = secret_subtract(2)
subtractor(3)
// -> 1
实现 secret_multiply。它应该返回一个函数,这个函数接受一个实参,并把它乘以传给 secret_multiply 的秘密值。
let multiplier = secret_multiply(7)
multiplier(3)
// -> 21
实现 secret_divide。它应该返回一个函数,这个函数接受一个实参,并用它除以传给 secret_divide 的秘密值。
let divider = secret_divide(3)
divider(32)
// -> 10
实现 secret_combine。它应该返回一个函数,这个函数接受一个实参,并按顺序把传给 secret_combine 的两个函数应用到它上面。
let multiply = secret_multiply(7)
let divide = secret_divide(3)
let combined = secret_combine(multiply, divide)
combined(6)
// -> 14