views:

283

answers:

3

Hi, how to get the value of the last element of a List? I've noted that List.hd (or .Head) return an item, while List.tl (or .Tail) returns a List.

Is rev the List and get the hd the only way around? Thanks.

A: 

The regular way to work with lists in F# is to use recursion. The first item in a list is the head (obviously) and the rest of the list is the tail (as oppose to the last item). So when a function recieves a list it processes the head and then recursively processes the rest of the list (the tail).

let reversedList = List.rev originalList
let tailItem = List.hd reversedList
Mitch Wheat
+9  A: 

In general, if you need to do this, you're doing something wrong. Since F# lists are single-linked, accessing the last element is costly - O(N), where N is size of list. Try to rewrite your algorithm so that you always access the first element, not the last (which is O(1)). If you cannot do so, chances are good that your choice of list for a data structure wasn't correct in the first place.

Pavel Minaev
Good points. I've presented a solution anyway, however.
Noldorin
+7  A: 

Try this function. It uses recursion, though it gets optimised to iteration anyway since it's tail recursion. In any case, it is most likely quicker than reversing the entire list (using List.rev).

let rec last = function
    | hd :: [] -> hd
    | hd :: tl -> last tl
    | _ -> failwith "Empty list."

The answer of Pavel Minaev is definitely worth taking into account, however. Nonetheless, the algorithm you have requested may be useful in some rare cases, and is the most efficient way to go about the task.

Noldorin
Since this is a tail recursive algorithm, the compiler will implement it as an efficient while loop. I tend to agree with Pavel regarding choice of data structure, but if you need to use a list then this is the right approach.
dahlbyk
@dahlbyk: Exactly. I meant to make a note about that, but it looks like I forgot - I shall add it now.
Noldorin