OCaml断言失败
大家好,我是OCaml新手,遇到了一些问题。所以我尝试做一个递归函数,它接受一个非空列表并返回最后一个元素。我的列表可以是任何数据类型。 下面是我现在看到的,它当前在断言语句中失败,该语句说“此表达式的类型为int,但表达式的类型应为int listOCaml断言失败,ocaml,Ocaml,大家好,我是OCaml新手,遇到了一些问题。所以我尝试做一个递归函数,它接受一个非空列表并返回最后一个元素。我的列表可以是任何数据类型。 下面是我现在看到的,它当前在断言语句中失败,该语句说“此表达式的类型为int,但表达式的类型应为int list let rec last l = match l with [] -> [] |[x] -> [x] |_::t -> last t ;; assert(last [1; 2; 3; 4] = 4);; assert(l
let rec last l = match l with
[] -> []
|[x] -> [x]
|_::t -> last t ;;
assert(last [1; 2; 3; 4] = 4);;
assert(last ["a"; "b"; "c"; "d"] = "d");;
问题在于函数确实返回了一个列表,从这两行可以看出:
[] -> []
|[x] -> [x]
您希望第二行是
|[x]->x
。当然,您还需要处理空列表的情况并有效地返回某些内容。您可以让它引发异常、使用选项类型或让调用方指定默认值。我经常发现,处理此类类型错误的一个好方法是用我想要的类型显式地注释函数应该是这样的——在这种情况下,我希望您希望第一行是这样的:
let rec last:'a list->'a=fun l->match l with
这样,错误将更改为:
File "1/hest.ml", line 5, characters 9-10:
5 | |[x] -> [x]
^
Error: This expression has type 'a list
but an expression was expected of type 'a
The type variable 'a occurs inside 'a list
这是一个更有用的错误。问题是,正如@PatJ在他的回答中所写的那样,当您编写函数时,实际上返回了一个包含一个元素的列表(或者当列表为空时没有元素),但是您对函数的使用似乎表明您只需要最后一个元素
您可以:
[4]
和[“d”]
进行比较,而不仅仅是值Some x
和None
而不是[x]
和[]
,并将断言更改为针对Some 1
和Some“d”
进行断言x
而不是[x]
,并在空列表情况下引发异常,即:failwith“empty list”
如果您选择异常,那么将函数重命名为
last\u exn
将向用户传达这样的信息,即他们必须小心函数可能会抛出异常。在这种情况下,最好使用选项类型:
让记录最后一次\u opt l=
匹配
|[]->无
|[x]->一些x
|\u x::t->last\u opt t
让()=
断言(最后一个选项[1;2;3;4]=大约4);
assert(last_opt[“a”;“b”;“c”;“d”]=Some“d”);(注意,这里可以使用字符,即“a”、“b”等,而不是字符串“a”、“b”等*)
断言(最后一个选项[]=无)
如果您确实不想要选项类型,则应小心处理空案例:
让rec最后一个l=
匹配
|[]->提升(故障“最后一次”)
|[x]->x
|_x::t->last t t
是的,我刚刚尝试了一下,得到了一个“这个表达式的类型是int,但表达式的类型应该是列表”这(几乎可以肯定)就是@PatJ所说的“你需要处理空列表的情况”。如果你将[x]
更改为x
,你需要更改[]
设置为非列表的某个值。没错,处理空列表案例的方式将改变您想要的解决方案。