I want to get the last element of a list and my logic is to reverse the list and to get its head:
module Program1 =
let last list =
let newList=List.rev list;
List.head newList;
newList
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (last list )
but it gives me this error
Error Type mismatch. Expecting a
unit list
but given a
int list
The type 'unit' does not match the type 'int'
Can anyone please help me?
Any element in list can be accessed using zero based index. If index is a negative number, count of index starts from end. As we want last element in list, use -1 as index.
you can use last property for read/write, inherited-getter: last is a returns the last element from the given list.
There is quite a lot to unpack here.
First, your function is not returning what you want it to return. See that last line there, the one that says newList
? That's your function's return value. The last line of the function body is its return value. So you're returning the reversed list, not the last element.
Second, since you're not returning the result of the List.head
call, you're ignoring it. Not doing anything with that result. Ignoring. And F# compiler tries to help you here: if you're ignoring a value, it means you're doing something wrong, and F# will complain (issue a warning) if you do that.
But there is one exception to that rule: you can ignore a value of type unit
. The logic goes, if you've got a value of type unit
, you must have obtained it as a result of producing a side-effect. Because if there was no side effect, and there is no resulting value (unit
means "no value"), then what was the point?
So, the compiler thinks like this: if you've ignored a value, then that value must be of type unit
. And since List.head newList
is of type unit
, then newList
must be of type unit list
. And therefore, list
must be of type unit list
. And therefore, your function is of type unit list -> unit list
(i.e. it takes a unit list
as parameter and returns another unit list
as result).
And since you're trying to pass an int list
into a function that takes a unit list
, the compiler can't stand it: Expecting a unit list but given a int list
.
And finally, reversing the list just to get at its last value is so very wasteful! You're reallocating a whole lot of memory that you don't really need. A less wasteful way to achieve this is via the use of recursion. Think about it this way: the last element of a one-element list is that one element, and the last element of a longer list is the last element of its tail. We can write that straight in F#:
let rec last list =
match list with
| [x] -> x // The last element of one-element list is the one element
| _::tail -> last tail // The last element of a longer list is the last element of its tail
| _ -> failwith "Empty list" // Otherwise fail
Plus, there is a ready-made function List.last
that you can just use (unless this is homework, in which case you should mention that in the question).
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (List.last list)
Beware, though, that there may not be a last element in the list - if the list is empty. In this case, List.last
(as well as List.head
) will crash with an exception, which is generally not a good idea. If you need to handle the empty-list case, look at List.tryLast
instead:
let mainP1()=
let list= [1; 2; 3]
match List.tryLast list with
| Some x -> printfn "Ultimul element al listei %A este %A" list x
| None -> printfn "Lista %A este goală" list
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With