Reputation: 239
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
Upvotes: 0
Views: 642
Reputation: 29106
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.
Upvotes: 2