OCaml Error involving lists - ocaml

I'm still fairly new to OCaml, and would like some assistance on optimizing code.
I'm trying to multiply each element of a given list by the list's last element.
Here's a snippet of my code:
(* Find the last element of a function *)
let rec lastE = function
| [] -> []
| [x] -> x
| _ :: t -> lastE t;;
(*multiply a list by the last element*)
let rec lmul list =
match list with
[] -> []
| hd::tl -> (hd *. (lastE tl)) :: lmul tl;;
When I run the code I get this error message:
Error: This expression has type float list but
an expression was expected of type 'a list list
I'm been studying it for a while, but any assistance on this problem will be much appreciated.

To rephrase differently what Dave Newman is telling you, your basic problem is that lastE needs to handle an empty list differently. If lastE is supposed to return a number, it has to return a number in all cases. As it stands, lastE returns a list when it receives an empty list.
If you don't want to use List.map (again as Dave Newman suggests), you might at least consider calling lastE just once rather than once for each element of the list. This will make a big difference for long lists.

Related

How to use List.fold_left to populate keys of empty string map in ocaml?

I have an existing list, which I would like to move into a empty StringMap. I just want the items in this list to become the keys of said StringMap.
This is what I'm trying to do right now:
utop # List.fold_left StringMap.empty [1,2,3];;
Error: This expression has type 'a StringMap.t
but an expression was expected of type 'b -> 'c -> 'b
But clearly it's wrong as I'm getting the above error message
How should I go about this? Thanks in advance
List.fold_left takes three parameters: a function to be "folded", an initial value, and the list to be processed. You're only supplying two parameters. You need to supply a function that processes each element of the list and produces an intermediate result.
Here is an example that adds up all the elements of a list:
# List.fold_left (fun a b -> a + b) 0 [1;3;5;7];;
- : int = 16
You need a function like the one above except that it should add an element to the map.

F# If statement type mismatch

i am in a bit of a pickle, i have tried for 2 hours straight trying to get this code to work and im lost.
let DropColumn list =
if List.exists List.isEmpty list then "empty value"
else
list |> List.map List.tail
This gives me an error error FS0001: The type 'string' does not match the type ''a list'
The usual way to deal with failure in functional programming is to use the Result type, which is essentially defined as:
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
To apply it to your code we can just wrap the string in the unhappy path with Error and the list from the happy path with Ok:
let DropColumn list =
if List.exists List.isEmpty list then
Error "empty value"
else
list |> List.map List.tail |> Ok
Then to use it you can use pattern matching:
match DropColumn myList with
| Ok newList ->
newList
| Error message ->
printfn "Error occurred: %s" message
[]
The answer given by #glennsl is correct and in many cases the preferred way. However, I'd like to add that there are two other common ways of dealing with invalid input:
Raise an exception. Use this for exceptional cases only, i.e. where you expect your code to halt as the result of invalid data. Do not use it for normal validation where you expect that data can often be wrong.
Use option. This is similar to using Result, but doesn't maintain information for the invalid case. This approach is very common and used a lot in library functions like List.tryFind, List.tryHead etc.
Raise an exception
In the comments you show you already know this option exists, but let's give it here for completeness:
let dropColumnOrRaise list =
if List.exists List.isEmpty list then failwith "empty value"
else
list |> List.map List.tail
Use option
This method usually requires that the business logic that shows an error or does recovery, goes elsewhere.
let tryDropColumn list =
if List.exists List.isEmpty list then None
else
list
|> List.map List.tail
|> Some
Use it as follows:
match tryDropColumn myCols with
| Some columns ->
// do something with valid columns, i.e., display them
printfn "%i columns remaining (List.length (List.head myCols))"
| None ->
// error recovery or showing a message
printfn "No column selected"
When you are dealing with several functions that operate on data that all return option, you can pipe them together with Option.bind (or Option.map if a function doesn't return option).
myCols
|> tryDropColumn
|> Option.map logColumns // function that always succeeds
|> Option.bind tryAtLeastTwoColumns // function that returns None on 1 or 0
|> Option.map showColumns
The code above removes the need to have a match x with for each returned option. Similar code can be used for Result from the previous answer.

Tranpose a list list in OCaml

let rec transpose list = match list with
| [] -> []
| [] :: xss -> transpose xss
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)
I found this code on this website and it transposes a list list or in my case a matrix from n × m to m × n.The only problem is I have no idea how it works. Can anyone please explain it step by step, line by line.
You should provide the link to the code as well, for context, or look on that question for an explanation.
Either way, I suspect other new OCaml programmers will come to this question looking for an answer.
-- After a quick Google search I believe this was the question you found the code from.
let rec transpose list = match list with
Create a function called transpose, make it recursive (rec) as we will make the function call itself. It will take an input parameter called list, where the type is determined by OCaml's type-system later.
Match the input parameter list with the following cases. That is, when the function finds a pattern matching those cases, it will execute that particular line of code. If code written does not cover all cases, OCaml will notify that not all cases are exhaustive and will cause a match_failure if it encounters cases that it doesn't cover.
First case:
| [] -> []
If we hit an empty list, return an empty list. This will end the recursion as the empty list is appended to the final result and returned. The empty list is a base case, where we meet a list with nothing inside, or it has recursed till there is nothing left. (the transpose of an empty list is ... and empty list)
| [] :: xss -> transpose xss
This is the case where there are still items in the list. Since it is a list of list, each element in the list we pass in is another list. i.e, [[1;2];[3;4]], so this function handles the case where we have [[];[1;2];[5;6]], it will skip the empty inner list, and then call transpose on the other [[1;2];[5;6]], since we don't need to transpose an empty list. Note that xss is the rest of the list (hence list of list), not just the next element only (which is just a list).
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)
This is the first case that will be matched when we pass in any regular list of list of length > 1, OCaml is able to match and also "unwrap" each element by breaking it down to fit the pattern, so we can immediately compute those elements without using nested match statements. In this case, we split the list of list into the (x::xs) list (first element) and the remaining list of list, xss. We could have also done it as x::xss but x will be a list that we need to break down into individual elements again.
For example, in [[1;2];[3;4]], (x::xs) will be [1;2] and xss will be [[3;4]]
(x :: List.map List.hd xss) will take the first element in the first list, in the given example, x will be 1. And apply that value to the List.hd of every item in xss list, (List.Map applies a function to every value in the list).
This is where it seems a little complicated. How you can look at it is: When you call List.hd [1;2;3] it will return 1 since it's the head. So when we do 3 :: List.map List.hd [[1;2]] it will return int list = [3; 1]. and it we did 3 :: List.map List.hd [[1;2];[4;5]] we get [3;1;4] as we are getting the head of every list inside the larger list, and appending 3 at the front of the resulting list.
If you did List.map List.tl [[1;2];[4;5]] instead your return type would be [2;5] since List.map applies the List.tl function to every list. You can use List.map to apply say a multiplication function (or anything complicated) to each item in the list in a quick and easy way.
The remaining transpose (xs :: List.map List.tl xss) just calls transpose to the remaining items in the list, which is the tail values of xss (all lists), appended with elements in xs. Try this out on paper if you feel you need a more concrete grasp on it.

OCaml: creating a record from a function

type node = {
lan: string;
lat: string;
};;
let rec read_nodes_from_list list = match list with
| Xml.Element("node", _, _)::list' -> {lan="A"; lat="B"}::read_nodes_from_list list'
;;
I tried this to create a node record but it doesn't work. And suppose I have another type that has same attributes of node, how can I tell ocaml which type object to create?
Thank you.
Obviously, your function didn't work because you forgot to match with empty list:
let rec read_nodes_from_list list = match list with
| Xml.Element("node", _, _)::list' -> {lan="A"; lat="B"}::read_nodes_from_list list'
| [] -> []
What you're actually trying to do is a map operation on list, so your function could be written more elegantly as follows:
let read_nodes_from_list list =
List.map (fun (Xml.Element("node", _, _)) -> {lan="A"; lat="B"}) list
However, the function may not work because pattern matching on Xml.Element is not exhaustive. You should be careful when handling remaining cases. For example, something like this would work:
let read_nodes_from_list list =
List.map (function | (Xml.Element("node", _, _)) -> {lan="A"; lat="B"}
| _ -> {lan=""; lat=""}) list
To answer your question about record types, it considers a bad practice to have two record types with the same field label. You still can put these record types in different submodules and distinguish them using module prefixes. But as I said, having two similar record types in the same module causes confusion to you and the OCaml compiler.

Value of the last element of a list

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.
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.
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.
A quick & dirty way of doing it is by using List.reduce. Assuming the list is called ls,
let lastElement ls = List.reduce (fun _ i -> i) ls
As for efficiency, I agree with Pavel.
A more concise version based on Mitch's answer:
let lastItem = myList |> List.rev |> List.head
The myList list is sent to List.rev function. The result is then processed by List.head
Agreed, not so efficient to get the last element of list, or any other "enumerable" sequence. That said, this function already exists in the Seq module, Seq.last.
As a novice F# developer, I don't see what the harm is in doing the following
let mylist = [1;2;3;4;5]
let lastValue = mylist.[mylist.Length - 1]
Imperative in nature? Yes but no need for recursion.
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
I think you can just write
list.[0..list.Length-1]
You can call List.Head to get the first element of a list, such that the below expression evaluates to true:
let lst = [1;2;3;4;5]
List.head lst = 1
However, calling List.Tail will return every element in the list after the first element, such that the below expression is true:
let lst = [1;2;3;4;5]
List.tail lst = [2;3;4;5]
Like some other people have mentioned, there isn't an efficient way in F# to get the tail end of a list, basic lists just aren't built with that functionality in mind. If you really want to get the last element you're going to have to reverse your list first, and then take the new head (which was the previous tail).
let lst = [1;2;3;4;5]
(List.head (List.rev lst) ) = 5
Below code worked fine with me, I've an array of integers, want to start from the 5th item, then take it minus the item number
Sum of [Array(xi) - Array(xi-5)] where i start at 5
The code used is:
series |> Array.windowed 5
|> Array.fold (fun s x ->
(x |> Array.rev |> Array.head) - (x |> Array.head) + s) 0
|> float
It's a very old question, but just in case someone comes here:
with FSharp 5, you can do x.[^index] where index will start at the end of the array / list.
let a = [1;2;3;4;5;6;7;8;9]
a.[^0] is 9
a.[^1] is 8
etc