Recursion OCaml-将数组转换为列表的尾部递归

Recursion OCaml-将数组转换为列表的尾部递归,recursion,ocaml,typeerror,Recursion,Ocaml,Typeerror,我想写一个带有尾部递归辅助函数的函数来将数组转换为列表 例如: #arraytolist [|"a";"b"|];; - :string list = ["a";"b"] #arraytolist [||];; - :'alist = [] 这是我的密码: let arraytolist arr = let rec helper alist index = if arr = [||] then [] else helper (arr.(index

我想写一个带有尾部递归辅助函数的函数来将数组转换为列表

例如:

#arraytolist  [|"a";"b"|];;
- :string list = ["a";"b"]
#arraytolist  [||];;
- :'alist = []
这是我的密码:

let arraytolist arr = 
    let rec helper alist index = 
        if arr = [||] then []
        else helper (arr.(index))::(List.tl alist) index+1
    in helper [] 0;;

Error: This expression has type int -> 'a list
       but an expression was expected of type 'a
       The type variable 'a occurs inside int -> 'a list

您的代码存在多个问题

第一个也是最直接的问题是没有正确地将参数插入到对
helper
的递归调用中。如果有疑问,你应该把整个论点放在括号里。我想它现在是这样解析的:
(helper arr.(index)):((List.tl-alist)index)+1

第二种情况是,当
arr
永不改变时,您的基本情况是
arr=[| |]
。因此,只有当
arr
最初为空时,这才是真的,否则递归将不会终止。当然,除非
index
越界并导致程序崩溃,因为您没有检查它,它会崩溃

第三个问题是,函数总是返回一个空列表,因为这是在基本情况下返回的(如果其条件正确的话)。你所做的一切都被丢弃了。有一种编写函数的方法,在这种方法中,返回一个空列表作为基本情况是有意义的,而且您似乎已经尝试了一半,但这种方法不是尾部递归的。您希望递归调用是每个迭代的最后一个操作,而不是递归调用结果的cons操作

第四个问题是,在每次迭代中使用
List.tl
,您都会丢弃
alist
的头部,这将在第一次迭代中失败,因为
alist
最初是空的。如果不是这样,
alist
将只包含最后处理的元素


我希望这能给你足够的时间去解决它。潜在的想法似乎很好;您只需删除错误。

您的代码存在多个问题

第一个也是最直接的问题是没有正确地将参数插入到对
helper
的递归调用中。如果有疑问,你应该把整个论点放在括号里。我想它现在是这样解析的:
(helper arr.(index)):((List.tl-alist)index)+1

第二种情况是,当
arr
永不改变时,您的基本情况是
arr=[| |]
。因此,只有当
arr
最初为空时,这才是真的,否则递归将不会终止。当然,除非
index
越界并导致程序崩溃,因为您没有检查它,它会崩溃

第三个问题是,函数总是返回一个空列表,因为这是在基本情况下返回的(如果其条件正确的话)。你所做的一切都被丢弃了。有一种编写函数的方法,在这种方法中,返回一个空列表作为基本情况是有意义的,而且您似乎已经尝试了一半,但这种方法不是尾部递归的。您希望递归调用是每个迭代的最后一个操作,而不是递归调用结果的cons操作

第四个问题是,在每次迭代中使用
List.tl
,您都会丢弃
alist
的头部,这将在第一次迭代中失败,因为
alist
最初是空的。如果不是这样,
alist
将只包含最后处理的元素


我希望这能给你足够的时间去解决它。潜在的想法似乎很好;你只需要剔除错误。

你能试着把问题描述得更清楚一点吗?“似乎有问题”不是一个非常有用的描述。请注意,对于输入数组
[|1;2;3 |]
,预期结果是
[1;2;3]
,这相当于
1::(2::(3:[])
。最好先构造最后一个元素,然后再回到第一个元素。你能试着更好地描述问题吗?“似乎有问题”不是一个非常有用的描述。请注意,对于输入数组
[|1;2;3 |]
,预期结果是
[1;2;3]
,这相当于
1::(2::(3:[])
。最好先构造最后一个元素,然后返回到第一个元素。