having trouble using F# functions - f#

I am new to F# and trying to learn how to use recursive function in F#. I am trying to play around with creating my own function and am having trouble getting it to work. What I have managed to do so far is get 10 random numbers and print them out. Both of those pieces of code I found online. I want to use the sort function(eventually it will be a sort function, but I am not asking for that) and am having trouble getting it to work. I put a // by where I think I am having trouble. I am not sure what this function will do, but as I wrote before I am just trying to play around with it
let randomNumberList count =
let rnd = System.Random()
List.init count (fun numbers -> rnd.Next (1, 1000))
let rec printList listx =
match listx with
| head :: tail -> printf "%d " head; printList tail
| [] -> printfn ""
let nonSortedList = randomNumberList 10
printList nonSortedList
let rec sort list =
match list with
| head :: tail -> sort tail
| [] -> 0
sort nonSortedList//I want to send the norSorted list into the sort function
printList nonSortedList//print out results after putting it into the sort function

You aren't assigning the results of sort to anything.
As F# is (largely) a functional language, it strongly encourages you to use immutable data structures. That means your data never changes, it is just passed to functions which use the data to create new representations of that data.
So your sort function is not changing the order of the list, rather it should return a new list that represents the ordered representation of the passed in list.
As F# expects this behaviour, if you don't do anything with the results F# is clever enough to know that you are probably doing something stupid.
So you should go :
let orderedList = sort nonSortedList
printList orderedList
If you really want to ignore the results - which sometimes you do, if your method has side effects and you are just calling it for its side effects - you can pass the results to ignore
sort nonSortedList |> ignore

Related

How would I implement a get Max element function in F#?

I am pretty new to F# and having trouble with some basic functions.
I am given a list:
let list1 = [1;2;3;4;5;6;7]
How would I create a getMax function that recursively iterates through list1 and finds the largest element?
What I am most confused about is what I would be returning and how I would iterate through the list.
Analogous to how, in an imperative language, you would loop through each item and store the maximum value in a variable, we write a tail-recursive function which will be translated by the compiler into a loop.
let getMax list =
let rec loop current list =
match list with
| [] -> current
| head::tail -> loop (if head > current then head else current) tail
loop (List.head list) list
This is verbose, but it's a good starting point.
Of course there's always List.max and List.maxBy, but understanding the analogue of a loop is an essential part of it.

Array pattern matching

Is it possible to iterate through an array using pattering matching just like we do with lists in F#? I tried something like this:
type Alphabet = A | B
let rec calc (l: Alphabet []) = match l with
|l when l.[0] = A -> 5+(calc l.[1..])
|l when l.[0] = B -> 10+(calc l.[1..])
|l when l = [||] -> 0
calc [|A;A;B|]
The problem seems to be that the loop goes on and results a stackoverflow. Is it possible to do so?
I think you are trying to do this:
let toInteger = function
| A -> 5
| B -> 10
[|A; A; B|] |> Array.sumBy toInteger
In pattern matching, you can use an array pattern: for example, [|a; b; c|] matches against a three-element array. But there is no :: operator for arrays, so it's cumbersome to use an array the way you'd use a list. This is because you can't get the array's tail as a new array without copying it.
There are a number of issues with the question's code:
It crashes due to going out of bounds of the array. This is because you are not verifying that the .[1..] slice exists.
It is not tail recursive. This may be the reason you're seeing a stack overflow on long lists.
Two features are mixed into one function, making it complicated to read: the conversion to integer and the summation.
The compiler cannot verify that the pattern match covers all cases, so it issues a warning.
As hinted before, the copying of arrays is costly. This algorithm has O(n^2) in the length of the array, making it extremely expensive for long arrays. Unlike Array.sumBy or a tail-recursive function indexing into the array, which don't have to copy the array at all.
The heart of the issue here is the difference between arrays and singly linked immutable lists. Arrays are suited for iterating over them by increasing an index (which Array.sumBy does internally), while lists allow to treat their tail as an independent list without any copying (which List.sumBy does internally). It's usually best to use each data structure the way it is intended to be used.

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

F# sort using head::tail

I am trying to write a recursive function that uses head::tail. I understand that head in the first element of the list and tail is all other elements in the list. I also understand how recursions works. What I am wondering is how to go about sorting the elements in the list. Is there a way to compare the head to every element in the tail then choose the smallest element? My background in C++ and I am not allowed to use the List.sort(). Any idea of how to go about it? I have looked at the tutorials on the msdn site and still have had no luck
Here is recursive list-based implementation of quicksort algorithm in F#
let rec quicksort list =
match list with
| [] -> []
| h::t ->
let lesser = List.filter ((>) h) t
let greater = List.filter ((<=) h) t
(quicksort lesser) #[h] #(quicksort greater)
You need to decide a sorting methodology before worrying about the data structure used. If you were to do, say, insertion sort, you would likely want to start from the end of the list and insert an item at each recursion level, being careful how you handle the insertion itself.
Technically at any particular level you only have access to one data element, however you can pass a particular data element as a parameter to preserve it. For instance here is the inserting part of an insertion sort algorithm, it assumes the list is sorted.
let rec insert i l =
match l with
| [] -> [i]
| h::t -> if h > i then
i::l
else
h::(insert i t)
Note how I now have access to two elements, the cached one and the remainder. Another variation would be a merge sort where you had two sorted lists and therefore two items to work with any particular iteration.
Daniel's commented answer mentions a particular implementation (quicksort) if you are interested.
Finally list's aren't optimal for sorting algorithms due to their rigid structure, and the number of allocations required. Given that all known sorting algorithms are > O(n) complexity, you can translate you list to and from an array in order to improve performance without hurting your asymptotic performance.
EDIT:
Note that above isn't in tail recursive format, you would need to do something like this:
let insert i l =
let rec insert i l acc =
match l with
| [] -> List.foldBack (fun e a -> e :: a) acc [i]
| h::t -> if h > i then
List.foldBack (fun e a -> e :: a) acc i::l
else
insert i l (i::acc)
insert i l []
I don't remember offhand the best way to reverse a list so went with an example from https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/lists

Resources