OCaml中如何用模式匹配实现数组set函数的纯函数式写法?
OCaml中用模式匹配实现数组set函数的方案
OCaml的模式匹配默认仅支持结构匹配(如匹配常量、构造器、元组结构等),无法直接在模式中编写> l-1这类数值比较逻辑,但可以通过**模式守卫(pattern guard)**实现带条件的匹配,这是最直接的解决方案,无需额外辅助函数。
用模式守卫实现原 imperative 版本
在模式分支后添加when关键字并跟上布尔条件,即可完成索引越界判断:
let set i v a = let l = Array.length a in match i with | idx when idx > l - 1 || idx < 0 -> raise (Invalid_argument "index out of bounds") | _ -> a.(i) <- v
这里额外补充了idx < 0的判断,因为索引为负数同样属于越界情况,和OCaml标准库的异常抛出逻辑保持一致。
纯函数式版本(返回新数组)
如果需要真正的纯函数式实现(不修改原数组,返回新数组),可以结合标准库的Array.mapi函数,同时用模式守卫做越界校验:
let set_pure i v a = let l = Array.length a in match i with | idx when idx < 0 || idx >= l -> raise (Invalid_argument "index out of bounds") | _ -> Array.mapi (fun idx val_ -> if idx = i then v else val_) a
这个版本不会修改输入的原数组,而是生成并返回一个新数组,其中指定索引位置的值被替换为v,完全符合纯函数式编程的要求。
关于模式匹配的限制
OCaml的模式匹配核心是基于结构等价性的匹配,比如你可以写| 0 -> ...匹配常量0,| (x, y) -> ...匹配二元组,但无法直接编写| > n -> ...这类范围匹配逻辑。模式守卫的作用就是为模式分支附加额外的布尔判断条件,从而扩展模式匹配的能力。
内容的提问来源于stack exchange,提问作者HeapUnderStop
相关产品推荐
相关产品推荐

