简体   繁体   English

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

[英]OCaml - Tail Recursion to convert array to list

I want to write function with a tail recursive helper function to convert array to list. 我想用尾部递归辅助函数编写函数以将数组转换为列表。

Example: 例:

#arraytolist  [|"a";"b"|];;
- :string list = ["a";"b"]
#arraytolist  [||];;
- :'alist = []

Here is my code: 这是我的代码:

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

There are multiple problems with your code. 您的代码有多个问题。

The first and most immediate problem is that you're not parenthesizing the arguments to the recursive call to helper correctly. 第一个也是最直接的问题是,您没有在括号内正确地递归调用helper If in doubt, you should put the entire argument in parenthesis. 如有疑问,应将整个参数放在括号中。 I think it's currently parsing it like this: (helper arr.(index)) :: (((List.tl alist) index) + 1) . 我认为它目前正在像这样解析它: (helper arr.(index)) :: (((List.tl alist) index) + 1)

The second is that your base case is arr = [||] when arr never changes. 第二个是您的基本情况是arr = [||]arr永不改变时)。 So this will only be true if arr is empty initially, otherwise the recursion will not terminate. 因此,只有当arr最初为空时,这才是正确的,否则递归不会终止。 Unless of course index goes out of bounds and causes the program to crash, which it will since you're not checking it. 当然,除非index超出范围并导致程序崩溃,否则将导致崩溃,因为您没有检查它。

The third problem is that your function will always return an empty list, since that's what you return in your base case (if its condition was correct). 第三个问题是您的函数将始终返回一个空列表,因为这是您在基本情况下返回的内容(如果条件正确)。 Everything else you've done is just discarded. 您所做的所有其他操作都将被丢弃。 There is a way to write your function where it does make sense to return an empty list as the base case, and it does seem like you're halfway trying to do that, but that approach wouldn't be tail recursive. 有一种编写函数的方法,在这种情况下,有必要返回一个空列表作为基本情况,而且似乎在尝试中途,但这并不是尾递归。 You'll want to have the recursive call be the last operation of each iteration, not a cons operation on the result of the recursive call. 您将希望递归调用是每次迭代的最后一个操作,而不是递归调用结果的cons操作。

And the fourth problem is that you're discarding the head of alist on every iteration by using List.tl , which will fail on the first iteration because alist is initially empty. 第四个问题是您使用List.tl在每次迭代中都丢弃了alist的头,这将在第一次迭代中失败,因为alist最初是空的。 And if it wasn't, alist would only ever contain the last element processed. 如果不是这样, alist永远只能包含处理的最后一个元素。

I hope this gives you enough to go on to get it figured out. 我希望这能给您足够的机会去解决它。 The underlying idea seems good; 基本思想似乎很好; you just need to weed out the mistakes. 您只需要清除错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM