OCaml中如何将number类型列表拆分为两个列表?
OCaml: 拆分含Int/Float构造子的number列表为两类元素列表
需求:实现一个函数,把包含
Int和Float构造子的number类型列表拆分成两个列表,分别存放Int和Float元素。示例:[Int(17);Float(18.9);Int(777);Float(15.5)]→([Int(17);Int(777)], [Float(18.9);Float(15.5)])
你提供的错误代码:
type number = | Int of int | Float of float let rec split_number_list: number list -> number list * number list = function lis -> match lis with |[] -> li,fi |(Int n)::l -> ((Int n)::li,fi) |(Float n)::l -> (li,(Float n)::fi)
问题1:Unbound value li/fi 的原因和解决
你代码里的li和fi完全未定义,OCaml无法识别它们。递归处理列表的核心逻辑是:先递归处理剩余子列表,拿到拆分后的两个结果列表,再把当前元素追加到对应列表的头部。
空列表的基准场景应该直接返回两个空列表([], [])——因为空列表里没有任何可拆分的元素。
问题2:正确的递归调用方式
处理非空列表时,需要先对剩余子列表rest调用split_number_list,解构它返回的元组(比如用let (int_list, float_list) = split_number_list rest),再把当前的Int或Float元素拼到对应列表的头部。
修正后的完整代码
type number = | Int of int | Float of float let rec split_number_list: number list -> number list * number list = function | [] -> ([], []) (* 基准情况:空列表返回两个空列表 *) | (Int n)::rest -> let (int_list, float_list) = split_number_list rest in ((Int n) :: int_list, float_list) (* 把当前Int元素加到递归得到的int列表头部 *) | (Float n)::rest -> let (int_list, float_list) = split_number_list rest in (int_list, (Float n) :: float_list) (* 把当前Float元素加到递归得到的float列表头部 *)
测试验证
调用示例:
split_number_list [Int(17);Float(18.9);Int(777);Float(15.5)];;
返回结果:
- : number list * number list = ([Int 17; Int 777], [Float 18.9; Float 15.5])
内容的提问来源于stack exchange,提问作者Dr.Hiluluk
相关产品推荐
相关产品推荐

