最初代码位于
List.flatten
(OCaml 标准库)中。但是,我不想使用标准库。因此我定义了 flatten
函数。 List.flatten
期间效果很好。在我实现 custom_flatten 后,它显示“错误:此模式与 'a * 'b 类型的值匹配,但需要一个与 int 类型的值匹配的模式”
我可以知道我的
custom_flatten
功能出了什么问题吗?
代码片段:
type move = Fill of int | Drain of int | Transfer of int * int;;
type state = {
jar_volumes: int list;
current_state: int list;
moves: move list;
}
let rec reversed lst =
let rec reverse acc = function
| [] -> acc
| head :: tail -> reverse (head :: acc) tail
in
reverse [] lst;;
let rec mapi_Two f index list =
match list with
| [] -> []
| x :: xs ->
let result = f index x in
result :: mapi_Two f (index + 1) xs
(*Error after implement this*)
let custom_flatten lst =
let rec aux acc = function
| [] -> acc
| [] :: xs -> aux acc xs
| (h :: t) :: xs -> aux (h :: acc) (t :: xs)
in
reversed (aux [] lst)
let generate_transfers jar_idx jar_count =
let transfer_indices =
init jar_count (fun target_idx -> (jar_idx, target_idx))
in
filter (fun (source, target) -> source <> target) transfer_indices
|> mapi_Two (fun (source, target) i -> Transfer (source, target))
(*The only flatten is in this function*)
let generate_possible_moves state =
let jar_count = length state.jar_volumes in
let generate_fills_and_drains jar_idx = [Fill jar_idx; Drain jar_idx] in
let generate_transfers jar_idx = generate_transfers jar_idx jar_count in
let moves_for_jar jar_idx =
(generate_fills_and_drains jar_idx) @ (generate_transfers jar_idx)
in
custom_flatten (mapi_Two (fun i _ -> moves_for_jar i) 0 state.jar_volumes)
let perform_move state move =
let new_state = doMove state.jar_volumes state.current_state move in
{ state with current_state = new_state; moves = move :: state.moves }
这个错误是我更改了
flatten
功能后才出现的。
Error: This pattern matches values of type 'a * 'b
but a pattern was expected which matches values of type int
RichardHuxton 编辑:这是您的实际错误及其指向的内容:
File "stackoverflow_20231025.ml", line 38, characters 19-35:
38 | |> mapi_Two (fun (source, target) i -> Transfer (source, target))
^^^^^^^^^^^^^^^^
Error: This pattern matches values of type 'a * 'b
but a pattern was expected which matches values of type int
那是我将
init jarcount ...
更改为List.init jarcount
之后。
所以(我是一个 ocaml 初学者,所以请仔细检查我的想法)你的
mapi_Two
定义如下:
let rec mapi_Two f index list =
...
let result = f index x in
...
所以 - 它接受一个函数、索引和列表,并将索引作为第一个参数传递给该函数。我假设索引是
int
。
然后当你调用它时:
mapi_Two (fun (source, target) i -> Transfer (source, target))
您正在传递
mapi_Two
一个接受 (source, target)
(这是错误消息中的 a * b
)而不是 int 的函数。