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

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.

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

How to properly create and use polynomial type and term type in f#

I'm trying to do this exercise:
I'm not sure how to use Type in F#, in F# interactive, I wrote type term = Term of float *int, Then I tried to create a value of type term by let x: term = (3.5,8);;But it gives an error.
Then I tried let x: term = Term (3.5,8);; and it worked. So Why is that?
For the first function, I tried:
let multiplyPolyByTerm (x:term, p:poly)=
match p with
|[]->[]
But that gives an error on the line |[]->[] saying that the expression is expecting a type poly, but poly is a in fact a list right? So why is it wrong here? I fixed it by |Poly[]->Poly[]. Then I tried to finish the function by giving the recursive definition of multiplying each term of the polynomial by the given term: |Poly a::af-> This gives an error so I'm stuck on trying to break down the Poly list.
If anyone has suggestion on good readings about Type in F#, please share it.
I got all the methods now, However,I find myself unable to throw an exception when the polynomial is an empty list as the base case of my recursive function is an empty list. Also, I don't know how to group common term together, Please help, Here are my codes:
type poly=Poly of (float*int) list
type term = Term of float *int
exception EmptyList
(*
let rec mergeCommonTerm(p:poly)=
let rec iterator ((a: float,b: int ), k: (float*int) list)=
match k with
|[]->(a,b)
|ki::kf-> if b= snd ki then (a+ fst ki,b)
match p with
|Poly [] -> Poly []
|Poly (a::af)-> match af with
|[]-> Poly [a]
|b::bf -> if snd a =snd b then Poly (fst a +fst b,snd a)::bf
else
*)
let rec multiplyPolyByTerm (x:term, p:poly)=
match x with
| Term (coe,deg) -> match p with
|Poly[] -> Poly []
|Poly (a::af) -> match multiplyPolyByTerm (x,Poly af) with
|Poly recusivep-> Poly ((fst a *coe,snd a + deg)::recusivep)
let rec addTermToPoly (x:term, p:poly)=
match x with
|Term (coe, deg)-> match p with
|Poly[] -> Poly [(coe,deg)]
|Poly (a::af)-> if snd a=deg then Poly ((fst a+coe,deg)::af)
else match addTermToPoly (x,Poly af) with
|Poly recusivep-> Poly (a::recusivep)
let rec addPolys (x:poly, y: poly)=
match x with
|Poly []->y
|Poly (xh::xt)-> addPolys(Poly xt,addTermToPoly(Term xh, y))
let rec multPolys (x:poly,y:poly)=
match x with
|Poly []-> Poly[]
|Poly (xh::xt)->addPolys (multiplyPolyByTerm(Term xh,y),multPolys(Poly xt,y))
let evalTerm (values:float) (termmm : term) :float=
match termmm with
|Term (coe,deg)->coe*(values**float(deg))
let rec evalPoly (polyn : poly, v: float) :float=
match polyn with
|Poly []->0.0
|Poly (ph::pt)-> (evalTerm v (Term ph)) + evalPoly (Poly pt,v)
let rec diffPoly (p:poly) :poly=
match p with
|Poly []->Poly []
|Poly (ah::at)-> match diffPoly (Poly at) with
|Poly [] -> if snd ah = 0 then Poly []
else Poly [(float(snd ah)*fst ah,snd ah - 1)]
|Poly (bh::bt)->Poly ((float(snd ah)*fst ah,snd ah - 1)::bh::bt)
As I mentioned in a comment, reading https://fsharpforfunandprofit.com/posts/discriminated-unions/ will be very helpful for you. But let me give you some quick help to get you unstuck and starting to solve your immediate problems. You're on the right track, you're just struggling a little with the syntax (and operator precedence, which is part of the syntax).
First, load the MSDN operator precedence documentation in another tab while you read the rest of this answer. You'll want to look at it later on, but first I'll explain a subtlety of how F# treats discriminated unions that you probably haven't understood yet.
When you define a discriminated union type like poly, the name Poly acts like a constructor for the type. In F#, constructors are functions. So when you write Poly (something), the F# parser interprets this as "take the value (something) and pass it to the function named Poly". Here, the function Poly isn't one you had to define explicitly; it was implicitly defined as part of your type definition. To really make this clear, consider this example:
type Example =
| Number of int
| Text of string
5 // This has type int
Number 5 // This has type Example
Number // This has type (int -> Example), i.e. a function
"foo" // This has type string
Text "foo" // This has type Example
Text // This has type (string -> Example), i.e. a function
Now look at the operator precedence list that you loaded in another tab. Lowest precedence is at the top of the table, and highest precedence is at the bottom; in other words, the lower something is on the table, the more "tightly" it binds. As you can see, function application (f x, calling f with parameter x) binds very tightly, more tightly than the :: operator. So when you write f a::b, that is not read as f (a::b), but rather as (f a)::b. In other words, f a::b reads as "Item b is a list of some type which we'll call T, and the function call f a produces an item of type T that should go in front of list b". If you instead meant "take the list formed by putting item a at the head of list b, and then call f with the resulting list", then that needs parentheses: you have to write f (a::b) to get that meaning.
So when you write Poly a::af, that's interpreted as (Poly a)::af, which means "Here is a list. The first item is a Poly a, which means that a is a (float * int) list. The rest of the list will be called af". And since the value your passing into it is not a list, but rather a poly type, that is a type mismatch. (Note that items of type poly contain lists, but they are not themselves lists). What you needed to write was Poly (a::af), which would have meant "Here is an item of type poly that contains a list. That list should be split into the head, a, and the rest, af."
I hope that helped rather than muddle the waters further. If you didn't understand any part of this, let me know and I'll try to make it clearer.
P.S. Another point of syntax you might want to know: F# gives you many ways to signal an error condition (like an empty list in this assignment), but your professor has asked you to use exception EmptyList when invalid input is given. That means he expects your code to "throw" or "raise" an exception when you encounter an error. In C# the term is "throw", but in F# the term is "raise", and the syntax looks like this:
if someErrorCondition then
raise EmptyList
// Or ...
match listThatShouldNotBeEmpty with
| [] -> raise EmptyList
| head::rest -> // Do something with head, etc.
That should take care of the next question you would have needed to ask. :-)
Update 2: You've edited your question to clarify another issue you're having, where your recursive function boils down to an empty list as the base case — yet your professor asked you to consider an empty list as an invalid input. There are two ways to solve this. I'll discuss the more complicated one first, then I'll discuss the easier one.
The more complicated way to solve this is to have two separate functions, an "outer" one and an "inner" one, for each of the functions you have been asked to define. In each case, the "outer" one checks whether the input is an empty list and throws an exception if that's the case. If the input is not an empty list, then it passes the input to the "inner" function, which does the recursive algorithm (and does NOT consider an empty list to be an error). So the "outer" function is basically only doing error-checking, and the "inner" function is doing all the work. This is a VERY common approach in professional programming, where all your error-checking is done at the "edges" of your code, while the "inner" code never has to deal with errors. It's therefore a good approach to know about — but in your particular case, I think it's more complicated than you need.
The easier solution is to rewrite your functions to consider a single-item list as the base case, so that your recursive functions never go all the way to an empty list. Then you can always consider an empty list to be an error. Since this is homework I won't give you an example based on your actual code, but rather an example based on a simple "take the sum of a list of integers" exercise where an empty list would be considered an error:
let rec sumNonEmptyList (input : int list) : int =
match input with
| [] -> raise EmptyList
| [x] -> x
| x::rest -> x + sumNonEmptyList rest
The syntax [x] in a match expression means "This matches a list with exactly one item in it, and assigns the name x to the value of that item". In your case, you'd probably be matching against Poly [] to raise an exception, Poly [a] as the base case, and Poly (a::af) as the "more than one item" case. (That's as much of a clue as I think I should give you; you'll learn better if you work out the rest yourself).

summing elements from a user defined datatype

Upon covering the predefined datatypes in f# (i.e lists) and how to sum elements of a list or a sequence, I'm trying to learn how I can work with user defined datatypes. Say I create a data type, call it list1:
type list1 =
A
| B of int * list1
Where:
A stands for an empty list
B builds a new list by adding an int in front of another list
so 1,2,3,4, will be represented with the list1 value:
B(1, B(2, B(3, B(4, A))))
From the wikibook I learned that with a list I can sum the elements by doing:
let List.sum [1; 2; 3; 4]
But how do I go about summing the elements of a user defined datatype? Any hints would be greatly appreciated.
Edit: I'm able to take advantage of the match operator:
let rec sumit (l: ilist) : int =
match l with
| (B(x1, A)) -> x1
| (B(x1, B(x2, A))) -> (x1+x2)
sumit (B(3, B(4, A)))
I get:
val it : int = 7
How can I make it so that if I have more than 2 ints it still sums the elemets (i.e. (B(3, B(4, B(5, A)))) gets 12?
One good general approach to questions like this is to write out your algorithm in word form or pseudocode form, then once you've figured out your algorithm, convert it to F#. In this case where you want to sum the lists, that would look like this:
The first step in figuring out an algorithm is to carefully define the specifications of the problem. I want an algorithm to sum my custom list type. What exactly does that mean? Or, to be more specific, what exactly does that mean for the two different kinds of values (A and B) that my custom list type can have? Well, let's look at them one at a time. If a list is of type A, then that represents an empty list, so I need to decide what the sum of an empty list should be. The most sensible value for the sum of an empty list is 0, so the rule is "I the list is of type A, then the sum is 0". Now, if the list is of type B, then what does the sum of that list mean? Well, the sum of a list of type B would be its int value, plus the sum of the sublist.
So now we have a "sum" rule for each of the two types that list1 can have. If A, the sum is 0. If B, the sum is (value + sum of sublist). And that rule translates almost verbatim into F# code!
let rec sum (lst : list1) =
match lst with
| A -> 0
| B (value, sublist) -> value + sum sublist
A couple things I want to note about this code. First, one thing you may or may not have seen before (since you seem to be an F# beginner) is the rec keyword. This is required when you're writing a recursive function: due to internal details in how the F# parser is implemented, if a function is going to call itself, you have to declare that ahead of time when you declare the function's name and parameters. Second, this is not the best way to write a sum function, because it is not actually tail-recursive, which means that it might throw a StackOverflowException if you try to sum a really, really long list. At this point in your learning F# you maybe shouldn't worry about that just yet, but eventually you will learn a useful technique for turning a non-tail-recursive function into a tail-recursive one. It involves adding an extra parameter usually called an "accumulator" (and sometimes spelled acc for short), and a properly tail-recursive version of the above sum function would have looked like this:
let sum (lst : list1) =
let rec tailRecursiveSum (acc : int) (lst : list1) =
match lst with
| A -> acc
| B (value, sublist) -> tailRecursiveSum (acc + value) sublist
tailRecursiveSum 0 lst
If you're already at the point where you can understand this, great! If you're not at that point yet, bookmark this answer and come back to it once you've studied tail recursion, because this technique (turning a non-tail-recursive function into a tail-recursive one with the use of an inner function and an accumulator parameter) is a very valuable one that has all sorts of applications in F# programming.
Besides tail-recursion, generic programming may be a concept of importance for the functional learner. Why go to the trouble of creating a custom data type, if it only can hold integer values?
The sum of all elements of a list can be abstracted as the repeated application of the addition operator to all elements of the list and an accumulator primed with an initial state. This can be generalized as a functional fold:
type 'a list1 = A | B of 'a * 'a list1
let fold folder (state : 'State) list =
let rec loop s = function
| A -> s
| B(x : 'T, xs) -> loop (folder s x) xs
loop state list
// val fold :
// folder:('State -> 'T -> 'State) -> state:'State -> list:'T list1 -> 'State
B(1, B(2, B(3, B(4, A))))
|> fold (+) 0
// val it : int = 10
Making also the sum function generic needs a little black magic called statically resolved type parameters. The signature isn't pretty, it essentially tells you that it expects the (+) operator on a type to successfully compile.
let inline sum xs = fold (+) Unchecked.defaultof<_> xs
// val inline sum :
// xs: ^a list1 -> ^b
// when ( ^b or ^a) : (static member ( + ) : ^b * ^a -> ^b)
B(1, B(2, B(3, B(4, A))))
|> sum
// val it : int = 10

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

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

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