I often find that a good way to deal with this kind of type errors, is to explicitly annotate the function with the type I want it to have - in this case, I expect that you want the first line to be something like this:
let rec last: 'a list -> 'a = fun l -> match l with
With that, the error changes to:
File "1/hest.ml", line 5, characters 9-10:
5 | |[x] -> [x]
^
Error: This expression has type 'a list
but an expression was expected of type 'a
The type variable 'a occurs inside 'a list
Which is a more helpful error. The problem is, as @PatJ writes in his answer, that as you have written the function you actually return a list with one element (or no elements, when the list is empty), but your usage of the function seems to indicate that you just want the last element.
You can either:
- change your usage of the function, so the asserts compare with
[4]
and ["d"]
instead of just the values.
- change the function to return
Some x
and None
instead of [x]
and []
, and change the asserts to assert against Some 1
and Some "d"
.
- change the function to return
x
instead of [x]
and throw an exception in the empty list case - that would be: failwith "empty list"
I think the second solution is the most natural one.
If you go for exceptions, then renaming the function to last_exn
would convey to users that they have to beware that the function might throw.