我在OCaml中为一个学校项目实现了我自己的版本。它被定义为这样的:OCaml中的模式类型错误
type 'a my_list =
| Item of ('a * 'a my_list)
| Empty
;;
我的目标是实现从列表模块20层的功能,并且第n是给了我很多的辛勤工作。它是一个递归函数,它也称为hd和长度函数。下面是代码:
let rec length my_list =
match my_list with
| Empty -> 0
| Item (hd, tl) -> (length tl) + 1
;;
let hd my_list = function
| Empty -> raise (Failure "hd")
| Item (hd, tl) -> hd
;;
let rec nth my_list n =
let len = (length my_list) in
match my_list with
| lz when lz < 0 -> raise (Invalid_argument "nth")
| sup when n > len - 1 -> raise (Failure "nth")
| 0 -> (hd my_list)
| _ -> (nth my_list (n - 1))
;;
在编译时,我得到这个错误:
$>ocamlc -w Aelz -warn-error A mylist.ml
File "mylist.ml", line 44, characters 10-11:
Error: This pattern matches values of type int
but a pattern was expected which matches values of type 'a my_list
参考以下行第n:| 0 -> (hd my_list)
什么想法? 谢谢
编辑1:谢谢大家对你的wiseful答案,这里是最后的代码:
let rec nth my_list n =
if n < 0 then raise (Invalid_argument "nth") else
if my_list = Empty then raise (Failure "nth") else
if n = 0 then hd my_list else nth (tl my_list) (n-1)
;;
编辑2:感谢您的建议,这个人是更强类型:
let rec nth my_list n =
if n < 0 then raise (Invalid_argument "nth") else
match my_list with
| Empty -> raise (Failure "nth")
| Item (hd, tl) -> if n=0 then hd else
nth tl (n-1)
;;
你不应该在'len'而不是'my_list'上匹配吗? – Marth
你是对的,谢谢! – bufferking
计算列表的长度不是要走的路:长度函数需要整个列表遍历,并且在每一次迭代中调用它!你是否曾经用一个计数器遍历列表的单个遍历,从0开始,并且当计数器到达N时返回元素到你所在的位置? – ghilesZ