如何将OCaml代码中`if b < a`条件改写为match模式匹配写法?
OCaml 递归函数条件判断转match结构实现
原始基于if..then的尾递归range2函数实现如下,功能是生成从a到b的整数区间列表,终止条件为上界b小于下界a:
# let rec range2 a b accum = if b < a then accum else range2 a (b - 1) (b :: accum);;
要把其中b < a的判断改写为合法的match..with结构,有两种常用实现方案:
方案1:使用when条件守卫(推荐,可读性最高)
OCaml模式匹配支持给分支追加when布尔守卫,只有模式匹配命中且守卫条件为真时,才会进入对应分支,逻辑和原if实现完全一一对应,是日常开发的首选写法:
let rec range2 a b accum = match () with | _ when b < a -> accum | _ -> range2 a (b - 1) (b :: accum)
这里我们匹配无实际含义的单元值(),两个分支都用通配符_覆盖所有情况,完全靠when后的条件做分支分流,执行逻辑和原代码完全一致。
方案2:匹配内建compare函数返回值(纯模式匹配无守卫)
如果不想使用when守卫,可以借助OCaml内建的全比较函数compare:compare x y的返回值遵循固定约定——x < y返回-1、x = y返回0、x > y返回1,直接匹配这个整数返回值即可实现分支判断:
let rec range2 a b accum = match compare b a with | -1 -> accum (* 该分支对应b < a的终止场景 *) | _ -> range2 a (b - 1) (b :: accum)
该写法完全依赖值匹配,没有额外守卫条件,但需要开发者熟悉compare的返回值约定,可读性略低于第一种方案。
注意:
match..with的模式位置仅支持结构解构、字面量匹配,不能直接放置b < a这类布尔运算表达式。非结构类的条件判断,要么通过when守卫实现,要么先将判断结果转为可匹配的具体值再做匹配。
内容的提问来源于stack exchange,提问作者Jam
相关产品推荐
相关产品推荐

