I'm trying to write a function in F# that inserts y into S, where y and S are sets of elements, in the returning set S elements should be inserted in order using <, if x exists in S then S is returned unchanged. I hope this is much clear. I have implemented the function as follows
let rec insert x S =
match S with
|[] -> x
|e::rest -> e::(insert x rest)
but it does not give me expected output. For example if
S = [2; 3]
x = [3; 4]
the output should be
[2; 3; 4]
But I'm getting
[2; 3; 3; 4]
I'm pretty new to f# and I'm having a hard time trying to extract a list of distinct values from a list:
let myList = [ 1; 2; 2; 3; 4; 3 ]
// desired list
[ 1; 2; 3; 4 ]
How do I do that? I see that seq has a distinct method, but not lists.
let myList = [ 1; 2; 2; 3; 4; 3 ]
let distinctList = myList |> Seq.distinct |> List.ofSeq
Result:
>
val myList : int list = [1; 2; 2; 3; 4; 3]
val distinctList : int list = [1; 2; 3; 4]
Next F# version (4.0) will have List.distinct function
Not sure if worse or better than Petr answer but you could also do :
let distinct xs = xs |> Set.ofList |> Set.toList
> distinct [ 1; 2; 2; 3; 4; 3 ];;
val it : int list = [1; 2; 3; 4]
I'm having some issues transforming a list of lists again. I have a list of list of ints it looks like this.
val p5PrimeFactorization : int list list =
[[1]; [2]; [3]; [2; 2]; [5]; [3; 2]; [7]; [2; 2; 2]; [3; 3]; [5; 2]; [11];
[3; 2; 2]; [13]; [7; 2]; [5; 3]; [2; 2; 2; 2]; [17]; [3; 3; 2]; [19];
[5; 2; 2]]
Now I want to transform each list into the product of all entries. Now this works
[for n in 2..20 -> primeFactors n 2 []]
|> List.map (List.sum)
But this doesn't..
[for n in 2..20 -> primeFactors n 2 []]
|> List.map (List.fold (fun acc elem -> acc * elem))
It seems the problem is that it infers the type of acc and elem to be of type int list which isn't right. I don't understand why List.sum which basically does the same thing except it returns the sum of all numbers, works, but my folder will not.
In your second example, you haven't specified the initial value for the fold.
You probably meant something like
|> List.map (List.fold (fun acc elem -> acc * elem) 1)
I want to create a list of 20 random numbers. I wrote this:
let numberList = [ 1 .. 20 ]
let randoms =
numberList
|> List.map (fun (x) -> System.Random().Next(0,9))
And I got this:
val numberList : int list =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20]
val randoms : int list =
[7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7; 7]
Which makes sense. The problem is that I want to pass in a random number each time the function is evaluated like this:
let numberList = [ 1 .. 20 ]
let randoms =
numberList
|> List.map (fun (Random().Next(0,9)) -> x)
but I am getting a "The pattern discriminator 'Random' is not defined" exception.
Am i approaching this problem the wrong way?
Thanks in advance
In your original version, you create a new Random object at each iteration. As this is seeded with the current time, you always create the same sequence.
You need to create the object outside map like so
let RNG = new System.Random()
numberlist |> List.map (fun x -> RNG.Next(0,9))
Although a more elegant solution would be
let RNG = new System.Random()
let randoms = List.init 20 (fun _ -> RNG.Next(0,9))
Your second version fails because you are trying to treat Random as a pattern which makes no sense in this situation.
I want to generate a sequence like a multiplication table. So for a start of 1 and a stop of 10 I am looking for a sequence like
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 1*1 - 1*10
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, // 2*1 - 2*10
3, 6, 9, 12, ... // 3*1 - 3*10
Here is my lame start at it, however I can't seem to figure out how to cleanly increment j when the stop is reached, or how to reset i back to the start.
let multable (start,stop) =
(start,start)
|> Seq.unfold(
fun (i,j) ->
Some(i*j, (i+1, j)))
let its = multable(1, 1)
let first10 = Seq.take 10 its
printf "%A" (Seq.to_list first10)
Which of course gives me 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
I can't really think of many cases where I'd prefer Seq.unfold over an equivalent list comprehension:
> let multiplication n m = [for a in 1 .. n -> [for b in 1 .. m -> a * b ] ];;
val multiplication : int -> int -> int list list
> multiplication 5 5;;
val it : int list list =
[[1; 2; 3; 4; 5]; [2; 4; 6; 8; 10]; [3; 6; 9; 12; 15]; [4; 8; 12; 16; 20];
[5; 10; 15; 20; 25]]
Occasionally the Array.init methods are useful too:
> let multiplication n m = Array2D.init n m (fun n m -> n * m);;
val multiplication : int -> int -> int [,]
> multiplication 5 5;;
val it : int [,] = [[0; 0; 0; 0; 0]
[0; 1; 2; 3; 4]
[0; 2; 4; 6; 8]
[0; 3; 6; 9; 12]
[0; 4; 8; 12; 16]]
Use a sequence expression:
let multable start stop = seq{
for a = start to stop do
for b = start to stop do
yield a*b
}
Output:
> multable 1 3 |> Seq.to_list;;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]
It's weird to represent a fundamentally 2d structure in this fashion. Why not a sequence of sequences:
let multable2 start stop = seq {
for a = start to stop do yield seq {
for b = start to stop do
yield a*b
}
}
Output:
val multable2 : int -> int -> seq<seq<int>>
> multable2 1 3 |> Seq.to_list;;
val it : seq<int> list = [seq [1; 2; 3]; seq [2; 4; 6]; seq [3; 6; 9]]
If you want to be "clever" and avoid multiplication:
let multable4 start stop = seq {
for a = start to stop do yield seq {
let s = ref 0 in
for b = start to stop do
s:=!s+a
yield !s
}
}
I don't actually see any nice prepackaged "sequence from a to b" outside of comprehensions/sequence expressions, although there's obviously [a..b] (list) and [|a..b|] (array) which you can project through Seq.unfold, Seq.map, etc. to make a Seq.
let Table r c =
[for row in 1..r do
yield [for col in 1..c do
yield row * col]]
printfn "%A" (Table 5 4)
// [[1; 2; 3; 4]; [2; 4; 6; 8]; [3; 6; 9; 12]; [4; 8; 12; 16]; [5; 10; 15; 20]]
Here's another way to use sequences:
let rec fromXToY x y =
seq {
if x <= y
then yield x; yield! fromXToY (x + 1) y;
else ()
}
let scaledSequence factor items =
Seq.map (fun x -> factor * x) items
let mulTable x y =
let sequenceOfIntegersMultipliedByValue = (fun n -> scaledSequence n (fromXToY x y))
let seqOfSeqOfValues = Seq.map sequenceOfIntegersMultipliedByValue (fromXToY x y)
// Convert the sequence of sequences to a simple sequence of values
Seq.fold Seq.append Seq.empty seqOfSeqOfValues