简体   繁体   中英

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. 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) .

The second is that your base case is arr = [||] when arr never changes. So this will only be true if arr is empty initially, otherwise the recursion will not terminate. Unless of course index goes out of bounds and causes the program to crash, which it will since you're not checking it.

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.

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. And if it wasn't, alist would only ever contain the last element processed.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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