OCaml实现doMove函数时遭遇类型不匹配错误的求助
OCaml实现doMove函数时遭遇类型不匹配错误的求助
嗨,我看到你在实现doMove函数时遇到了类型不匹配的问题,咱们来一步步定位问题并解决它。
首先看你收到的错误提示:"This expression has type int list but an expression was expected of type int",这个错误的根源其实出在你调用自定义mapi函数的地方。
你定义的mapi函数需要三个参数:带索引的处理函数f、初始索引值index,以及要处理的列表list,签名是这样的:
let rec mapi f index list = ...
但你在doMove里调用它时,只传了两个参数:
mapi (fun i content -> ...) jar_content
这里漏掉了初始索引参数(应该传0,因为列表索引从0开始)。OCaml的类型检查器会尝试匹配参数,它把jar_content(int list类型)当成了第二个需要int类型的index参数,自然就抛出了类型不匹配的错误。
另外还有个小优化点:你两次调用transfer_water_from_M_to_N,其实可以先把结果存下来,避免重复计算,让代码更高效。
修正后的完整代码如下:
type move = Transfer of int * int let rec nth lst x = match lst with | [] -> raise (Failure "Not Found") | h :: t -> if x = 0 then h else nth t (x - 1) let min x y = if x > y then y else x let rec mapi f index list = match list with | [] -> [] | x :: xs -> let result = f index x in result :: mapi f (index + 1) xs let fst (a, _) = a let snd (_, b) = b let rec doMove jar_volumes jar_content move = let transfer_water_from_M_to_N m n jar_volumes jar_content = let jarM_volume_index = nth jar_volumes m in let jarN_volume_index = nth jar_volumes n in let jarM_content_index = nth jar_content m in let jarN_content_index = nth jar_content n in if jarM_content_index > 0 && jarN_content_index < jarN_volume_index then let compare_min_amount = min jarM_content_index (jarN_volume_index - jarN_content_index) in let new_jarM_content = jarM_content_index - compare_min_amount in let new_jarN_content = jarN_content_index + compare_min_amount in (new_jarM_content, new_jarN_content) else (jarM_content_index, jarN_content_index) in match move with | Transfer (m, n) -> (* 先计算一次转移结果,避免重复调用 *) let (new_m_content, new_n_content) = transfer_water_from_M_to_N m n jar_volumes jar_content in let updated_jar_content = mapi (fun i content -> if i = m then new_m_content else if i = n then new_n_content else content) 0 (* 补上初始索引0 *) jar_content in updated_jar_content
现在测试你给出的例子(这里注意你的例子里转移参数可能写反了,应该是Transfer (0, 1)才会得到[3;2]的结果):
doMove [5; 2] [5; 0] (Transfer (0, 1))
运行后会正确返回[3; 2],符合预期。
备注:内容来源于stack exchange,提问作者lucas lootan
相关产品推荐
相关产品推荐

