In this F# code how is the firstElem getting a value? - f#

In the below F# code how the firstElem getting a value? I got the code from the below this link.
let rec quicksort list =
match list with
| [] -> // If the list is empty
[] // return an empty list
| firstElem::otherElements -> // If the list is not empty
let smallerElements = // extract the smaller ones
otherElements
|> List.filter (fun e -> e < firstElem)
|> quicksort // and sort them
let largerElements = // extract the large ones
otherElements
|> List.filter (fun e -> e >= firstElem)
|> quicksort // and sort them
// Combine the 3 parts into a new list and return it
List.concat [smallerElements; [firstElem]; largerElements]

Your text indentation somehow got messed up when copying the text. In the original code from the link the let bindings of smallerElements and largerElements are both further indented than the match | firstElem::otherElements ->. So the answer is that firstElem gets its value from the matching with the head of the parameter/variable list.
Edit: The term head refers to the Head and the Tail of a list. The Head is the first element, and the Tail is all of the rest of the elements. E.g.
let ns = [1; 2; 3; 4]
let h = ns.Head
let t = ns.Tail
will return
val ns : int list = [1; 2; 3; 4]
val h : int = 1
val t : int list = [2; 3; 4]
with the caveat that Head and Tail is not defined for an empty list.
The lines
match list with
| firstElem::otherElements ->
will match the Head of list with firstElem and the Tail with otherElements.

Related

F# algorithm for hk

Can anyone help me with this problem?
"Realize a function which duplicate each item in a list. You can use List.map"
IN F# sharp language.
And also
"Use the List.init function to generate a list of n random natural numbers between 0 and m."
let makeCopy elem Count =
match Count with
| 0 -> []
| 1 -> elem
let rec dupeElem row count =
match row with
| [] -> []
| hd::tl -> (makeCopy hd count) # dupeElem tl count
//let xs = [1; 2; 3]
//xs |> List.collect (fun x -> List.replicate 3 x)
//val it : int list = [1; 1; 2; 2; 3; 3]
Duplicating the items is pretty straight forward, you just need a recursive function that walks the list.
Generating the random numbers is where you can use List.init to create a new list. You can use the .NET Random class to generate the random numbers you're after.
This gives up the following functions:
let rec duplicateItems list =
match list with
| [] -> []
| head :: tail -> head :: head :: duplicateItems tail
let makeRandomList count upperBound =
let random = Random()
List.init count (fun i -> random.Next(0, upperBound))
You can now generate a random list and pipe it into the duplicate function:
let numbers = makeRandomList 10 20 |> duplicateItems
NOTE: duplicateItems is not tail recursive, so for really large lists this might be an issue. You can get around this by treating the data to duplicate as a sequence:
let duplicateSequence sequence =
seq {
for a in sequence do
yield a
yield a
}
Now we just need to pipe the result into Seq.toList:
let numbers = makeRandomList 10 20 |> duplicateSequence |> Seq.toList
We could also have written makeRandom to return a sequence rather than a list. This would have made the whole computation lazy up until the point we call Seq.toList.
which duplicate each item in a list. You can use List.map
I think your own solution with List.collect is fine. But here's one with List.map:
> let dupe x = List.map (fun s -> [s;s]) x |> List.concat
val dupe : x:'a list -> 'a list
> dupe [1;2;3];;
val it : int list = [1; 1; 2; 2; 3; 3]
Use the List.init function to generate a list of n random natural numbers between 0 and m
I'll show you the general idea, then you can work out the rest, I'm sure. This basically works:
> let rand n max = let r = Random() in List.init n (fun _ -> r.Next(0, max));;
val rand : n:int -> max:int -> int list
> rand 10 12;;
val it : int list = [11; 11; 10; 11; 6; 1; 3; 6; 8; 2]

Reversing a list then adding new item

I am trying to learn F#, and I'm trying to create some simple functions as part of this learning.
I have created a function that adds an item to a list then reverses the result. This works very nicely in the F# interactive window in Visual Studio
let addThenReverse n list =
match list with
| [] -> []
| _ -> n::list |> List.rev
addThenReverse 0 [1;2;3] //results in [3; 2; 1; 0]
But I'm having difficulty with writing a function that would reverse a list then add an item to it.
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> List.rev list |> n::list
reverseThenAdd 9 [1;2;3] //desired result [3; 2; 1; 9]
EDIT
The desired result for the above should be [9; 3; 2; 1]. Well done to those who spotted this!
This second function does not compile and I receive the warning 'This expression was expected to have type 'a list -> 'b list but here has type 'c list'
Any variants I try seem to result other compilation errors. I assume (but don't know how) that I need to use the new list created as a result of 'List.rev list', perhaps by assigning it to a variable.
The issue is that you are passing the reversed list to a concatenation expression, and that throws off the compiler. You should do:
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> n :: (List.rev list)
reverseThenAdd 9 [1;2;3] //desired result [3;2;1;9]
which means that you are adding n to the list resulting from (List.rev list)
I'm a little confused by your desired results. Luiso has a version of your code that will fix the compiler, but it won't fit your desired result. With
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> n :: (List.rev list)
reverseThenAdd 9 [1;2;3] //desired result [3; 2; 1; 9]
the actual result will be [9; 3; 2; 1]. If the comment is a typo, and that is in fact your desired result, then Luiso's answer works. Otherwise, there is no material difference between addThenReverse and reverseThenAdd, because "add" means something different (appending and prepending) in each case.
Note that I think in both cases, the first case should be
| [] -> [n]
rather than
| [] -> []
In fact, I don't think you need the match statement at all. I think the mathematically correct formulation would be:
let addThenReverse n list = n::list |> List.rev
let reverseThenAdd n list = n::(list |> List.rev)
Then you would have
addThenReverse 0 [] // result: [0]
reverseThenAdd 0 [] // result: [0]
addThenReverse 9 [1; 2; 3] // result: [3; 2; 1; 9]
reverseThenAdd 9 [1; 2; 3] // result: [9; 3; 2; 1]
ADDENDUM
I'm a fan of expressive code. As elegant as F# is, it is still possible to write code that obscures what you're actually trying to do. The code above works, but you can make it more expressive, and learn a bit more about how the language works, by using the composition operator:
let add n list = n::list
let reverse = List.rev
let addThenReverse n = add n >> reverse
let reverseThenAdd n = reverse >> add n
This gives the same results as before, but it expresses what you're doing more clearly. True to the spirit of functional programming, you're telling the compiler what to do, rather than how to do it.
let reverseThenAdd n list = List.rev list # [n]

Tail Recursive Combinations

I have this code:
let rec combinations acc listC =
match listC with
| [] -> acc
| h::t ->
let next = [h]::List.map (fun t -> h::t) acc # acc
combinations next t
It looks tail recursive, but I keep getting stack overflows with it. Any ideas on how to make it work?
combinations is tail recursive. Your problem is with the # operator. Appending a list with it iterates the whole list, so as your acc becomes large, you will get a SO.
You can see here, that the # operator is not tail recursive. The non-optimized version looks like: let rec (#) x y = match x with [] -> y | (h::t) -> h :: (t # y).
To get around this problem, there are a couple of options:
If you don't care about order, you could write a tail-recursive method to prepend the result like this:
let rec prepend lst1 lst2 =
match lst1 with
| [] -> lst2
| head::tail -> prepend tail (head::lst2)
> prepend [1;2;3;4] [5;6;7;8];;
val it : int list = [4; 3; 2; 1; 5; 6; 7; 8]
If you care about order, you could write a method to first reverse the list and then prepend it. The drawback of this, of course, is that it will require twice as much memory since you are allocating an additional list to hold the reversed version of the original list. You can reuse the previous function to write something like this:
let prepend2 lst1 lst2 =
prepend (prepend lst1 []) lst2
> prepend2 [1;2;3;4] [5;6;7;8];;
val it : int list = [1; 2; 3; 4; 5; 6; 7; 8]

Remove a single non-unique value from a sequence in F#

I have a sequence of integers representing dice in F#.
In the game in question, the player has a pool of dice and can choose to play one (governed by certain rules) and keep the rest.
If, for example, a player rolls a 6, 6 and a 4 and decides to play one the sixes, is there a simple way to return a sequence with only one 6 removed?
Seq.filter (fun x -> x != 6) dice
removes all of the sixes, not just one.
Non-trivial operations on sequences are painful to work with, since they don't support pattern matching. I think the simplest solution is as follows:
let filterFirst f s =
seq {
let filtered = ref false
for a in s do
if filtered.Value = false && f a then
filtered := true
else yield a
}
So long as the mutable implementation is hidden from the client, it's still functional style ;)
If you're going to store data I would use ResizeArray instead of a Sequence. It has a wealth of functions built in such as the function you asked about. It's simply called Remove. Note: ResizeArray is an abbreviation for the CLI type List.
let test = seq [1; 2; 6; 6; 1; 0]
let a = new ResizeArray<int>(test)
a.Remove 6 |> ignore
Seq.toList a |> printf "%A"
// output
> [1; 2; 6; 1; 0]
Other data type options could be Array
let removeOneFromArray v a =
let i = Array.findIndex ((=)v) a
Array.append a.[..(i-1)] a.[(i+1)..]
or List
let removeOneFromList v l =
let rec remove acc = function
| x::xs when x = v -> List.rev acc # xs
| x::xs -> remove (x::acc) xs
| [] -> acc
remove [] l
the below code will work for a list (so not any seq but it sounds like the sequence your using could be a List)
let rec removeOne value list =
match list with
| head::tail when head = value -> tail
| head::tail -> head::(removeOne value tail)
| _ -> [] //you might wanna fail here since it didn't find value in
//the list
EDIT: code updated based on correct comment below. Thanks P
EDIT: After reading a different answer I thought that a warning would be in order. Don't use the above code for infite sequences but since I guess your players don't have infite dice that should not be a problem but for but for completeness here's an implementation that would work for (almost) any
finite sequence
let rec removeOne value seq acc =
match seq.Any() with
| true when s.First() = value -> seq.Skip(1)
| true -> seq.First()::(removeOne value seq.Skip(1))
| _ -> List.rev acc //you might wanna fail here since it didn't find value in
//the list
However I recommend using the first solution which Im confident will perform better than the latter even if you have to turn a sequence into a list first (at least for small sequences or large sequences with the soughtfor value in the end)
I don't think there is any function that would allow you to directly represent the idea that you want to remove just the first element matching the specified criteria from the list (e.g. something like Seq.removeOne).
You can implement the function in a relatively readable way using Seq.fold (if the sequence of numbers is finite):
let removeOne f l =
Seq.fold (fun (removed, res) v ->
if removed then true, v::res
elif f v then true, res
else false, v::res) (false, []) l
|> snd |> List.rev
> removeOne (fun x -> x = 6) [ 1; 2; 6; 6; 1 ];
val it : int list = [1; 2; 6; 1]
The fold function keeps some state - in this case of type bool * list<'a>. The Boolean flag represents whether we already removed some element and the list is used to accumulate the result (which has to be reversed at the end of processing).
If you need to do this for (possibly) infinite seq<int>, then you'll need to use GetEnumerator directly and implement the code as a recursive sequence expression. This is a bit uglier and it would look like this:
let removeOne f (s:seq<_>) =
// Get enumerator of the input sequence
let en = s.GetEnumerator()
let rec loop() = seq {
// Move to the next element
if en.MoveNext() then
// Is this the element to skip?
if f en.Current then
// Yes - return all remaining elements without filtering
while en.MoveNext() do
yield en.Current
else
// No - return this element and continue looping
yield en.Current
yield! loop() }
loop()
You can try this:
let rec removeFirstOccurrence item screened items =
items |> function
| h::tail -> if h = item
then screened # tail
else tail |> removeFirstOccurrence item (screened # [h])
| _ -> []
Usage:
let updated = products |> removeFirstOccurrence product []

F# Split list into sublists based on comparison of adjacent elements

I've found this question on hubFS, but that handles a splitting criteria based on individual elements. I'd like to split based on a comparison of adjacent elements, so the type would look like this:
val split = ('T -> 'T -> bool) -> 'T list -> 'T list list
Currently, I am trying to start from Don's imperative solution, but I can't work out how to initialize and use a 'prev' value for comparison. Is fold a better way to go?
//Don's solution for single criteria, copied from hubFS
let SequencesStartingWith n (s:seq<_>) =
seq { use ie = s.GetEnumerator()
let acc = new ResizeArray<_>()
while ie.MoveNext() do
let x = ie.Current
if x = n && acc.Count > 0 then
yield ResizeArray.to_list acc
acc.Clear()
acc.Add x
if acc.Count > 0 then
yield ResizeArray.to_list acc }
This is an interesting problem! I needed to implement exactly this in C# just recently for my article about grouping (because the type signature of the function is pretty similar to groupBy, so it can be used in LINQ query as the group by clause). The C# implementation was quite ugly though.
Anyway, there must be a way to express this function using some simple primitives. It just seems that the F# library doesn't provide any functions that fit for this purpose. I was able to come up with two functions that seem to be generally useful and can be combined together to solve this problem, so here they are:
// Splits a list into two lists using the specified function
// The list is split between two elements for which 'f' returns 'true'
let splitAt f list =
let rec splitAtAux acc list =
match list with
| x::y::ys when f x y -> List.rev (x::acc), y::ys
| x::xs -> splitAtAux (x::acc) xs
| [] -> (List.rev acc), []
splitAtAux [] list
val splitAt : ('a -> 'a -> bool) -> 'a list -> 'a list * 'a list
This is similar to what we want to achieve, but it splits the list only in two pieces (which is a simpler case than splitting the list multiple times). Then we'll need to repeat this operation, which can be done using this function:
// Repeatedly uses 'f' to take several elements of the input list and
// aggregate them into value of type 'b until the remaining list
// (second value returned by 'f') is empty
let foldUntilEmpty f list =
let rec foldUntilEmptyAux acc list =
match f list with
| l, [] -> l::acc |> List.rev
| l, rest -> foldUntilEmptyAux (l::acc) rest
foldUntilEmptyAux [] list
val foldUntilEmpty : ('a list -> 'b * 'a list) -> 'a list -> 'b list
Now we can repeatedly apply splitAt (with some predicate specified as the first argument) on the input list using foldUntilEmpty, which gives us the function we wanted:
let splitAtEvery f list = foldUntilEmpty (splitAt f) list
splitAtEvery (<>) [ 1; 1; 1; 2; 2; 3; 3; 3; 3 ];;
val it : int list list = [[1; 1; 1]; [2; 2]; [3; 3; 3; 3]]
I think that the last step is really nice :-). The first two functions are quite straightforward and may be useful for other things, although they are not as general as functions from the F# core library.
How about:
let splitOn test lst =
List.foldBack (fun el lst ->
match lst with
| [] -> [[el]]
| (x::xs)::ys when not (test el x) -> (el::(x::xs))::ys
| _ -> [el]::lst
) lst []
the foldBack removes the need to reverse the list.
Having thought about this a bit further, I've come up with this solution. I'm not sure that it's very readable (except for me who wrote it).
UPDATE Building on the better matching example in Tomas's answer, here's an improved version which removes the 'code smell' (see edits for previous version), and is slightly more readable (says me).
It still breaks on this (splitOn (<>) []), because of the dreaded value restriction error, but I think that might be inevitable.
(EDIT: Corrected bug spotted by Johan Kullbom, now works correctly for [1;1;2;3]. The problem was eating two elements directly in the first match, this meant I missed a comparison/check.)
//Function for splitting list into list of lists based on comparison of adjacent elements
let splitOn test lst =
let rec loop lst inner outer = //inner=current sublist, outer=list of sublists
match lst with
| x::y::ys when test x y -> loop (y::ys) [] (List.rev (x::inner) :: outer)
| x::xs -> loop xs (x::inner) outer
| _ -> List.rev ((List.rev inner) :: outer)
loop lst [] []
splitOn (fun a b -> b - a > 1) [1]
> val it : [[1]]
splitOn (fun a b -> b - a > 1) [1;3]
> val it : [[1]; [3]]
splitOn (fun a b -> b - a > 1) [1;2;3;4;6;7;8;9;11;12;13;14;15;16;18;19;21]
> val it : [[1; 2; 3; 4]; [6; 7; 8; 9]; [11; 12; 13; 14; 15; 16]; [18; 19]; [21]]
Any thoughts on this, or the partial solution in my question?
"adjacent" immediately makes me think of Seq.pairwise.
let splitAt pred xs =
if Seq.isEmpty xs then
[]
else
xs
|> Seq.pairwise
|> Seq.fold (fun (curr :: rest as lists) (i, j) -> if pred i j then [j] :: lists else (j :: curr) :: rest) [[Seq.head xs]]
|> List.rev
|> List.map List.rev
Example:
[1;1;2;3;3;3;2;1;2;2]
|> splitAt (>)
Gives:
[[1; 1; 2; 3; 3; 3]; [2]; [1; 2; 2]]
I would prefer using List.fold over explicit recursion.
let splitOn pred = function
| [] -> []
| hd :: tl ->
let (outer, inner, _) =
List.fold (fun (outer, inner, prev) curr ->
if pred prev curr
then (List.rev inner) :: outer, [curr], curr
else outer, curr :: inner, curr)
([], [hd], hd)
tl
List.rev ((List.rev inner) :: outer)
I like answers provided by #Joh and #Johan as these solutions seem to be most idiomatic and straightforward. I also like an idea suggested by #Shooton. However, each solution had their own drawbacks.
I was trying to avoid:
Reversing lists
Unsplitting and joining back the temporary results
Complex match instructions
Even Seq.pairwise appeared to be redundant
Checking list for emptiness can be removed in cost of using Unchecked.defaultof<_> below
Here's my version:
let splitWhen f src =
if List.isEmpty src then [] else
src
|> List.foldBack
(fun el (prev, current, rest) ->
if f el prev
then el , [el] , current :: rest
else el , el :: current , rest
)
<| (List.head src, [], []) // Initial value does not matter, dislike using Unchecked.defaultof<_>
|> fun (_, current, rest) -> current :: rest // Merge temporary lists
|> List.filter (not << List.isEmpty) // Drop tail element

Resources