F# print all element from the list one by one using recursion - f#

Imagine that I have function printList that takes list as an argument and prints all the elements in the list one by one in a new row followed by the position in the list also while having space between them.
E.G
1: 4
2: 9
3: 12
How can I implement this in F# using recursion without any built-in features ?
I assume it might look something like this, but I've problems with int, unit types.
let rec printList l = function
match l with
| [] -> 0
| head::tail -> // something

There are two advices I can give you so you can implement the printList function:
you will have to make printList a non-recursive function and define a local recursive helper function in order to keep track of the index of the value.
all branches of your match expression must return the same type and here what you want is the unit type.
In case you are still stuck, I provide the solution below.
Solution
let printList list =
let rec helper index list =
match list with
| [] -> ()
| head :: tail ->
printfn "%d: %A" index head
helper (index + 1) tail
helper 1 list

Related

F# - Insert element in sorted list (tail-recursive)

I am trying to convert the following normal-recursive code to tail-recursive in F#, but I am failing miserably.
let rec insert elem lst =
match lst with
| [] -> [elem]
| hd::tl -> if hd > elem then
elem::lst
else
hd::(insert elem tl)
let lst1 = []
let lst2 = [1;2;3;5]
printfn "\nInserting 4 in an empty list: %A" (insert 4 lst1)
printfn "\nInserting 4 in a sorted list: %A" (insert 4 lst2)
Can you guys help? Unfortunately I am a beginner in f#. Also, can anyone point me to a good tutorial to understand tail-recursion?
The point of tail recursion is the following: the last operation before returning from a function is a call to itself; this is called a tail call, and is where tail recursion gets its name from (the recursive call is in last, i.e. tail position).
Your function is not tail recursive because at least one of its branches has an operation after the recursive call (the list cons operator).
The usual way of converting a recursive function into a tail-recursive function is to add an argument to accumulate intermediate results (the accumulator). When it comes to lists, and when you realize that the only elementary list operation is prepending an element, this also means that after you are through with processing your list, it will be reversed, and thus the resulting accumulator will usually have to be reversed again.
With all these points in mind, and given that we do not want to change the function's public interface by adding a parameter that is superfluous from the caller's point of view, we move the real work to an internal subfunction. This particular function is slightly more complicated because after the element has been inserted, there is nothing else to do but concatenate the two partial lists again, one of which is now in reverse order while the other is not. We create a second internal function to handle that part, and so the whole function looks as follows:
let insert elm lst =
let rec iter acc = function
| [] -> List.rev (elm :: acc)
| (h :: t) as ls ->
if h > elm then finish (elm :: ls) acc
else iter (h :: acc) t
and finish acc = function
| [] -> acc
| h :: t -> finish (h :: acc) t
iter [] lst
For further studying, Scott Wlaschin's F# for Fun and Profit is a great resource, and tail recursion is handled in a larger chapter about recursive types and more: https://fsharpforfunandprofit.com/posts/recursive-types-and-folds

Noob question about F# function parameter where the parameter is a list

I'm trying to play around with creating functions in F#, In the image below, I'm trying to create a function that takes a list of floats and sum the values in the list. I don't know how to pass a list as parameter in a function so I tried this to get the head of a list but the code doesn't work:
let sumlist l=
printf "%f" l.Head
Then I see some people does:
let sumlist l:float=
match l with
| [] -> 0.0
| e::li -> e + sumlist li
So is l:float the way you pass a list to a function? so like l:string would be a list of string?
But I saw list l has l.Head function to return the first element in the list(As it seems that we can't access arbitrary elements in the list like an array) but
let sumlist l:float=
printfn "%f" l.Head
gives type mismatch error.
I also don't understand the recursive code provided, I don't understand this line
| e::li -> e + sumlist li
What is ::? and Li?
Thank you for clarifying this for me!
So your first example doesn't return anything and that's because you're calling printfn which prints to the console instead of returning your types. e :: li here represents a list where e is the head and li is the rest of the list. The :: here lets the compiler know that you want to deconstruct the list.
//fully annotated
let s (l: float list) :float =
l.Head
//here the types can be inferred without any annotation
let rec sumlist l =
match l with
| [] -> 0.0
| e::li -> e + sumlist li
s [0.7]
//returns 0.7
sumlist [0.4;0.5;0.6]
//returns 1.5
In my first example if you try and remove the type annotations you'll notice that you get an error. This is because l.Head's type is ambiguous otherwise did you call l.Head on a list of strings, floats? In the sumlist function I provided you can see that I didn't need to annotate, and this is because I'm adding them up and that constrains the types.
Personally when starting I highly recommend always annotating the types. (l : float list) or (l: list<float>) is a way to say my input is a list of floats, and :float at the end how we say the return type is a float. You'll notice I put a rec keyword on our recursive function, it's better to explicitly declare whenever you make a recursive function.
Syntax questions
So is l:float the way you pass a list to a function?
No. Most of the time the compiler can figure out that you are passing a list without annotating the parameter as a list, but when it doesn't, you annotate is
l : 'a list // where 'a is generic type
// OR
l : float list // where type is specified as float
What is ::? and Li?
When pattern matching a list, [] matches to empty list, which here is used as the recursion end criteria. The other match separates head (e) from the rest of the list aka tail (li). If there is only one item in list, then li evaluates as [].
Additional note for your recursive code: You are missing the recursion keyword rec eg.
let rec sumlist ...
Recursive function implementation
The easiest way would be to use the sum function of List eg.
[0.4; 0.5; 0.6] |> List.sum // Returns 1.5
But, if you want to create this function yourself, consider using tail-recursion for better performance and to avoid stack overflow with bigger input lists.
let sumlist (values : float list) =
let rec sum (acc : float) (remaining : float list) =
match remaining with
| [] -> acc
| head :: tail -> sum (acc + head) tail
sum 0. values
Which is called
[0.4; 0.5; 0.6] |> sumlist // Returns 1.5
The difference here to a normal recursion is that each recursion calculates its own values and is not dependent on other recursions yet to come to finish its calculations.

F#: error creating a list of size n

I'm trying to create a list of size n pulling elements from a larger, already created list.
I'm getting an error saying:
This value is not a function and cannot be applied.
Incomplete pattern matches on this expression. For example, the value '[]' may indicate a case not covered by the pattern(s). at 7,16
Can anyone help see what I'm doing wrong? Also, I'm trying to understand F# so I don't really want anything that can do what I'm asking for me, unless it's an FYI kind of thing. But I'd still want help creating a function to do this.
//create a list of size n from beginning of a dataset
let populateList n =
let starterList = []
let data = [1;2;3;4;5;6;7;8]
let rec helper count aList =
let head::tail = aList
if count < k then head :: helper count+1 tail else []
helper 0 data
populateList 3
It's failing to run because of this:
head :: helper count+1 tail
Because function invocations have higher operator precedence than the infix + operator, this is being interpreted as:
head :: ((helper count) + (1 tail))
Since 1 is not a function, you are getting an error here.
You can fix this by adding parentheses:
head :: helper (count+1) tail
The "Incomplete pattern matches" warning will not prevent it from running, but it does indicate something that you should address because it can lead to a runtime error.
The correct way to address it is by using pattern matching to cover all the possible patterns:
let rec helper count aList =
match aList with
| head::tail -> if count < n then head :: helper (count+1) tail else []
| [] -> []
This will ensure that you do not attempt to split an empty list into a head and a tail.
Since this function now returns [] both in the base case and in the case that aList is empty, you can further simplify this by using when and a default match condition:
let rec helper count aList =
match aList with
| head::tail when count < n -> head :: helper (count+1) tail
| _ -> []

F# on List of Elements

I am trying to write a F# function that finds the biggest value. I am new to F# and am confused as to how to implement this with the correct type and recursion.
Any help would be greatly appreciated along with an explanation of how it works, I really need to understand how it works so I can attempt to create other F# functions. Thanks!
When creating recursive functions, start thinking about the corner cases. Your helper function takes a list and a "maximum so far". Corner cases: What if your list is empty? What if you only have a 1 element list, or focus on the first element? That directly translates into a match statement:
let rec helper (l, m) =
match l, m with
| [], m -> m
| (l1 :: rest), m ->
let max1 = if l1 > m then l1 else m
helper(rest, max1)
I'll leave the wrapper findMax open, but clearly you can solve that using the same thinking: What if you get an empty list? (scream!) What if you get a list with elements (the first element is your maximum so far, feed the rest of the list into your helper)
And of course you could put it all into one function. I've chosen this rather roundabout helper because your template code was shaped in that way.
The first thing to do is to start thinking recursively and/or mathematically. In most general vague terms, it should look like "The result of my function is..." - then try to actually put into words what the result should be.
Applying to your particular problem, I would phrase it like this:
when given a list of one element, the result of findMax is that element.
when given a list of more than one element, the result of findMax is the maximum of the lists's head and the maximum element of its tail.
This thinking can be translated into F# almost word for word:
let rec findMax list =
match list with
| [x] -> x
| head::tail -> max head (findMax tail)
where:
let max a b = if a > b then a else b
Note, however, that this function is incomplete: it doesn't specify what the result should be when given an empty list. I will leave this as an exercise for the reader.

Comparing values in loop inside function

I want to make a function that takes an integer list as argument and compares every value and returns the largest value. In C# I would simply iterate through every value in the list, save the largest to a variable and return it, I'm hoping F# works similarly but the syntax is kinda iffy for me, here's what my code looks like. Also max2 is a function that compares 2 values and returns the largest.
let max_list list =
let a = 0 : int
match list with
| head :: tail -> (for i in list do a = max2 i a) a
| [] -> failwith "sry";;
You could use mutable variable and write the code using for loop, just like in C#. However, if you're doing this to learn F# and functional concepts, then it's good idea to use recursion.
In this case, recursive function is a bit longer, but it demonstrates the key concepts including pattern matching - so learning the tricks is something that will be useful when writing more complicated F# code.
The key idea is to write a function that takes the largest value found so far and calls itself recursively until it reaches the end of the list.
let max_list list =
// Inner recursive function that takes the largest value found so far
// and a list to be processed (if it is empty, it returns 'maxSoFar')
let rec loop maxSoFar list =
match list with
// If the head value is greater than what we found so far, use it as new greater
| head::tail when head > maxSoFar -> loop head tail
// If the head is smaller, use the previous maxSoFar value
| _::tail -> loop maxSoFar tail
// At the end, just return the largest value found so far
| [] -> maxSoFar
// Start with head as the greatest and tail as the rest to be processed
// (fails for empty list - but you could match here to give better error)
loop (List.head list) (List.tail list)
As a final note, this will be slow because it uses generic comparison (via an interface). You can make the function faster using let inline max_list list = (...). That way, the code will use native comparison instruction when used with primitive types like int (this is really a special case - the problem only really happens with generic comparison)
Also know that you can write a nice one-liner using reduce:
let max_list list = List.reduce (fun max x -> if x > max then x else max)
If your intention is to be able to find the maximum value of items in a list where the value of the items is found by the function max2 then this approach works:
let findMax list =
list
|> List.map (fun i -> i, max2 i)
|> List.maxBy snd
|> fst

Resources