在 ML 系列语言中,人们倾向于使用模式匹配来if/else
构建。在 F# 中,if/else
在许多情况下,在模式匹配中使用守卫可以轻松替换。
例如,一个简单的delete1
函数可以在不使用的情况下重写if/else
(参见参考资料delete2
):
let rec delete1 (a, xs) =
match xs with
| [] -> []
| x::xs' -> if x = a then xs' else x::delete1(a, xs')
let rec delete2 (a, xs) =
match xs with
| [] -> []
| x::xs' when x = a -> xs'
| x::xs' -> x::delete2(a, xs')
另一个例子是求解二次函数:
type Solution =
| NoRoot
| OneRoot of float
| TwoRoots of float * float
let solve1 (a,b,c) =
let delta = b*b-4.0*a*c
if delta < 0.0 || a = 0.0 then NoRoot
elif delta = 0.0 then OneRoot (-b/(2.0*a))
else
TwoRoots ((-b + sqrt(delta))/(2.0*a), (-b - sqrt(delta))/(2.0*a))
let solve2 (a,b,c) =
match a, b*b-4.0*a*c with
| 0.0, _ -> NoRoot
| _, delta when delta < 0.0 -> NoRoot
| _, 0.0 -> OneRoot (-b/(2.0*a))
| _, delta -> TwoRoots((-b + sqrt(delta))/(2.0*a),(-b - sqrt(delta))/(2.0*a))
我们应该使用带有守卫的模式匹配来忽略丑陋的if/else
构造吗?
将模式匹配与警卫一起使用是否有任何性能影响?我的印象是它似乎很慢,因为在运行时检查了模式匹配。