为什么可以';我不能将这两个列表传递到OCaml中的递归函数中吗?
我试图用OCaml编写一个更简单的解析器,但遇到了一个无法克服的问题。我将代码简化为一个简单的示例,这给了我相同的错误: 我想用OCaml编写一个函数,它接收整数列表并输出字符串列表。 规则是,如果一行中有两个为什么可以';我不能将这两个列表传递到OCaml中的递归函数中吗?,ocaml,Ocaml,我试图用OCaml编写一个更简单的解析器,但遇到了一个无法克服的问题。我将代码简化为一个简单的示例,这给了我相同的错误: 我想用OCaml编写一个函数,它接收整数列表并输出字符串列表。 规则是,如果一行中有两个1s,则输出“十一个”,如果只有一个1,则输出“一个” 对于任何其他数字,它输出“其他”。此python代码执行以下任务: def转换(数字、名称): 如果len(数字)==0: 返回名称 n=数字。pop(0) 如果n==1: 如果len(数字)>0且数字[0]==1: 数字。流行音乐(
1
s,则输出“十一个”
,如果只有一个1
,则输出“一个”
对于任何其他数字,它输出“其他”。此python代码执行以下任务:
def转换(数字、名称):
如果len(数字)==0:
返回名称
n=数字。pop(0)
如果n==1:
如果len(数字)>0且数字[0]==1:
数字。流行音乐(0)
名称。附加(“十一”)
其他:
名称。附加(“一”)
其他:
名称。附加(“其他”)
返回转换(数字、名称)
转换([1,1,2,1,3,1],)
#->['11'、'other'、'one'、'other'、'one']
我在OCaml中的尝试如下:
let rec convert(数字:int list)(名称:string list)=函数
|[]->List.rev名称
|1::1::t->convert t(“十一”::名称)
|1::t->convert t(“一”::名称)
|_u3;::t->convert t(“其他”::名称)
;;
转换[1;1;2;3][];;
我认为将发生的是convert
将递归地调用自身:整数列表将变小,而
字符串的最大值,直到不再剩下整数:
convert [1; 1; 2; 1; 3; 1] []
-> convert [2; 1; 3; 1] ["eleven"]
-> convert [1; 3; 1] ["other"; "eleven"]
-> convert [3; 1] ["one"; "other"; "eleven"]
-> convert [1] ["other"; "one"; "other"; "eleven"]
-> convert [] ["one"; "other"; "one"; "other"; "eleven"]
-> ["eleven"; "other"; "one"; "other"; "one"]
但实际发生的是编译错误:
Error: This expression has type int list -> string list
but an expression was expected of type string list
突出显示文本convert(“十一”::名称)
这是怎么回事?我不明白为什么这不起作用。
函数|…
实际上是fun x->match x with |…
的缩写。即:
let convert numbers names = function
| ...
相当于
let convert numbers names something_else =
match something_else with
| ...
因此,您的convert
函数需要三个参数,convert t(“十一”::名称)
返回一个函数int list->string list
,而不仅仅是从第一个分支推断出的string list
将函数
替换为将数字与
匹配以编译:
let rec convert (numbers : int list) (names : string list) =
match numbers with
| [] -> List.rev names
| 1 :: 1 :: t -> convert t ("eleven" :: names)
| 1 :: t -> convert t ("one" :: names)
| _ :: t -> convert t ("other" :: names)
;;
convert [1; 1; 2; 3] [];;
function |…
实际上是funx->match x with |…
的缩写。即:
let convert numbers names = function
| ...
相当于
let convert numbers names something_else =
match something_else with
| ...
因此,您的convert
函数需要三个参数,convert t(“十一”::名称)
返回一个函数int list->string list
,而不仅仅是从第一个分支推断出的string list
将函数
替换为将数字与
匹配以编译:
let rec convert (numbers : int list) (names : string list) =
match numbers with
| [] -> List.rev names
| 1 :: 1 :: t -> convert t ("eleven" :: names)
| 1 :: t -> convert t ("one" :: names)
| _ :: t -> convert t ("other" :: names)
;;
convert [1; 1; 2; 3] [];;
或者只需从原始代码中删除
number
,然后调用convert[][1;1;2;3]
。通过最后一次输入,您还可以将名称作为可选参数,默认为[],这意味着您可以只调用convert[1;1;2;3]
,这样做是正确的。或者只需从原始代码中删除number
,然后调用convert[][1;1;2;3]
。通过最后一次输入,您还可以将名称作为可选参数,默认为[],这意味着您可以调用convert[1;1;2;3]
,这样做是正确的。