递归是指某事物能够用自身来定义。在 F# 中,递归最常见于递归函数,也就是调用自身的函数。
递归函数至少需要一个_基本情况_和一个_递归情况_。_基本情况_返回一个值,不再调用函数自身。_递归情况_会再次调用函数,并修改输入,使其最终能满足基本情况。
递归函数的定义方式与普通函数类似,但要使用rec修饰符。没有这个修饰符,函数就_不能_调用自身,任何这样做的尝试都会导致编译错误。因此,必须显式启用递归。
let rec factorial x =
// Base case
if x = 1 then
1
// Recursive case
else
x * factorial (x - 1)
F# 还通过可区分联合类型支持递归类型。递归可区分联合类型的一个或多个案例会在其数据中引用该可区分联合类型自身。和递归函数一样,递归类型也必须有一个基本情况。与递归函数不同,递归类型不使用rec关键字。
type RussianDoll =
| Doll // Base case
| Layer of RussianDoll // Recursive case
在这个练习中,你在一家为顾客提供外送服务的披萨店工作。
店里提供三种披萨:
顾客还可以支付少量额外费用,选择两种附加选项:
顾客下单时,如果只订购一到两个披萨,还会收取一笔额外费用:
你有三个任务,每个任务都会处理披萨及其价格。
定义 Pizza 可区分联合,用来表示披萨类型以及可以添加到一个披萨上的两个附加选项:
MargheritaCapreseFormaggioExtraSauceExtraToppings实现 pizzaPrice 函数,用来计算一个披萨的价格:
pizzaPrice Caprese
// => 9
实现 orderPrice 函数,用来计算一份披萨订单的价格:
orderPrice [Margherita; Formaggio]
// => 19