Combine Observables - f#

Let say I have
A: IObservable<int>
B: IObservable<int>
how can I combine these two into
C: IObservable<int>
which emitted value is a product of last observed values of A and B?
E.g.
A = [ 2 3 1 ]
B = [ 2 5 6 ]
then
C = [ 4 6 15 18 6 ]

I'm not terribly good at f# (more like a novice), but this seems to work:
let a = new Subject<int>()
let b = new Subject<int>()
let c = Observable.CombineLatest(a, b, Func<_,_,_>(fun x y -> x * y))
c.Subscribe(fun x -> printfn "%i" x) |> ignore
a.OnNext(2)
b.OnNext(2)
a.OnNext(3)
b.OnNext(5)
b.OnNext(6)
a.OnNext(1)
I get:
4
6
15
18
6

Related

Drop duplicates except for the first occurrence with Deedle

I have a table with one key with duplicate values. I would like to drop/reduce all duplicate keys but preserve the first row of each duplicate.
let data = "A;B\na;1\nb;\nb;2\nc;3"
let bytes = System.Text.Encoding.UTF8.GetBytes data
let stream = new MemoryStream( bytes )
let df=
Frame.ReadCsv(
stream = stream,
separators = ";",
hasHeaders = true
)
df.Print()
A B
0 -> a 1
1 -> b <missing>
2 -> b 2
3 -> c 3
The result should be
A B
0 -> a 1
1 -> b <missing>
2 -> c 3
I have tried applyLevel but I only get the value not the first entry:
let df1 =
df
|> Frame.groupRowsByString "A"
|> Frame.applyLevel fst (fun s -> s |> Series.firstValue)
df1.Print()
A B
a -> a 1
b -> b 2 <- wrong
c -> c 3
This is essentially a duplicate of a previous SO question. The short answer is:
let df1 =
df
|> Frame.groupRowsByString "A"
|> Frame.nest // convert to a series of frames
|> Series.mapValues (Frame.take 1) // take the first row from each frame
|> Frame.unnest // convert back to a single frame
|> Frame.mapRowKeys snd
df1.Print()
The output is:
A B
0 -> a 1
1 -> b <missing>
3 -> c 3
I've added a call to Frame.mapRowKeys at the end to match your desired output as closely as possible. Note that the actual output differs slightly from your expected output, because row 3 -> c 3 has original index 3 instead of 2. I think this is more correct, but you can renumber the rows if necessary.
The referenced question has more details.
Using Frame.nest/Frame.unnest is a reasonable solution. I have noticed, it is a little bit slow.
My solution involves putting the keys in a Map and checking:
let dropDuplicates (df:Frame<_,_>) =
let selectedMap =
df.RowKeys
|> Seq.fold (fun (m:Map<'A,'B>) (a,b) ->
if m.ContainsKey a then m else m |> Map.add a b) Map.empty
df
|> Frame.filterRows(fun (a,b) _ ->
match selectedMap.TryFind a with
| Some entry -> entry = b
| _ -> false)
let df1 =
df
|> Frame.groupRowsByString "A"
|> dropDuplicates
df1.Print()
A B
a 0 -> a 1
b 1 -> b <missing>
c 3 -> c 3

F# function, how it really works

I got function like this one.
let c = (fun a b ‐> let d = a 10 in d ‐ 4*b) (fun c ‐> c + c) 5
let x = c‐6
That's what I understand so far:
"fun c ‐> c + c" is first argument for "fun a b" and "5" is second.
"let d" is kind a function that takes "a" and "b" and returns the result.
But if somebody could explain what exactly happened in:
let d = a 10 in d ‐ 4*b
in is used here as part of verbose syntax. You can rewrite it in leightweight syntax to make it a bit more readable. It would be something like that:
fun a b =
let d = a 10
d - 4 * b
a is invoked with 10 as argument and the results is assigned to d. Later on d - 4 * b is calculated and returned from the function.
For the example you have a is fun c -> c + c so invoking it with 10 returns 20.
20 - 4 * 5 = 0 so c is set to 0 and x will be 0 - 6 = -6.
From F# interactive:
> let c = (fun a b -> let d = a 10 in d - 4*b) (fun c -> c + c) 5;;
val c : int = 0

F# problems calling a function that takes a integer and return a string

I'm pretty new to programming in F#, and I am working on a project at the moment, with a function that takes an integer and returns a string value.
My problem (se my code below) is that no matter what I do, I cant return the values of my str, calling my function.
let mulTable (n:int):string = string n
let mutable m = 1
let mutable str = ""
while m < 10 do
str <- "m\t" + str
m <- m + 1
printfn "%A" (mulTable str)
My idea here is that I want to store the value of m, in str, så that str in the end of my while loop contains the values of "1 2 3 4 5 6 7 8 9". But no matter what I try my printfn "%A" mulTable str, returns "this expressions was exspected to have type int, but here has type string". I have tried converting my str to a string in my mutable value like:
let mutable str = ""
let mutable str1 = str |> int
and then I try to call my str1 using function mulTable instead of calling str. But still it does not work.
What am I missing here? I've been trying every single possible solution I can think of, without being able to solve my problem.
A fix of your own algorithm could be:
let getSequenceAsString max =
let concat s x = sprintf "%s\t%i" s x
let mutable m = 1
let mutable str = ""
while m < max do
str <- concat str m
m <- m + 1
str
printfn "%A" (getSequenceAsString 10)
But as others have shown it's a lot of work that can be done more easily:
open System
let getSequenceAsString max =
String.Join("\t", [1..max-1])
If you want each number reverted as you ask for in a comment it could be done this way:
let getSequenceAsString min max =
let revert x =
let rec rev y acc =
match y with
| 0 -> acc
| _ -> rev (y / 10) (sprintf "%s%i" acc (y % 10))
rev x ""
String.Join("\t", ([min..max-1] |> List.map revert))
printfn "%A" (getSequenceAsString 95 105)
Gives:
"59 69 79 89 99 001 101 201 301 401"
You can easily join an array of strings into a string array, and then print it out if necessary.
open System
let xs = [1..9] |> List.map string
//you should avoid using mutable variables, and instead generate your list of numbers with an list comprehension or something similar.
String.Join("\t", xs)
//A little exploration of the List/Array/String classes will bring this method up: "concatenates the members of a collection using the separator string.
This gives me:
val it : string = "1 2 3 4 5 6 7 8 9"
I've adjusted the code to make it produce results similar to what you wanted:
let mulTable (n:int):string = string n
let mutable m = 1
let mutable str = ""
while m < 10 do
str <- mulTable m+ "\t" + str
m <- m + 1
printfn "%A" (str)
I've used your mulTable to convert m to string, but for printfn you don't need to use that, because str is already a string.
Still the result would be 9 8 7 6 5 4 3 2 1
There are more then one way to revert the string, one of them would be to split the string into an array of characthers and then revert the array. From resulting array we will build a new string again. It would look something like:
printf "%A" (new System.String(str.ToCharArray() |> Array.rev ))
Edit
To achieve the same result, I would suggest to use more functional style, using recursion and avoiding mutating variables.
let getNumbersString upperLimit =
let rec innerRecursion rem acc=
match rem with
| 0 -> acc
| _ -> innerRecursion (rem-1) (sprintf "%i "rem::acc)
innerRecursion upperLimit [] |> String.concat ""
getNumbersString 9
Will result in
val it : string = "1 2 3 4 5 6 7 8 9 "

how to read file and skip some white spaces

this is similiar to my previous question,
but there is another improvisation, how is the code if i want to skip some white spaces, for this case is "enter", for example:
5 5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
<- this white space
3 4 4
1 2 3 4
1 2 3 4
1 2 3 4
i try to my best but couldn't find how to skip the white space
thank you for the help :)
This is the answer, thanks to Ramon :
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in (lines |> Array.toSeq |> Seq.skip 1 |> Seq.filter(System.String.IsNullOrEmpty >> not)) do
yield l.Split()
|]
x,y,n,data
Another way to write your readMap function is to use if expression inside the list comprehension. I think this is actually more readable if you're using comprehensions (because you don't have to combine two ways of writing things):
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in lines |> Seq.skip 1 do
if not (System.String.IsNullOrEmpty(l)) then
yield l.Split()
|]
x,y,n,data
I also removed the call to Array.toSeq, because F# allows you to use array in a place where seq is expected without an explicit conversion (seq is actually IEnumerable and array implements it).
What about this:
val items : string list
items
|> List.filter (System.String.IsNullOrEmpty >> not)
?

help me explain this F# recursive example program

let rec aggregateList (f:int->int->int) init list =
match list with
| [] -> init
| hd::tl ->
let rem = aggregateList f init tl
f rem hd
let add a b = a + b
let mul a b = a * b
//to use in F# Interactive:
//aggregateList add 0 [1..5];;
Got this example from "Functional Programming for the Real world" by Thomas Petricek
I don't understand in second branch in that pattern matching: f rem hd.
Could somebody help me?
Let's break down the aggregateList function declaration first. The function takes three parameters:
A function, named f, that takes two ints and returns a third int.
The initial value to start aggregating with.
A list of values.
The function then matches the list it is supplied with one of two possibilities:
The list is empty, in which case it returns the value of init.
The list is not empty, in which case it takes the first item and assigns it to hd (or head) and the rest of the list and assigns it to tl (or tail). Then it performs the recursive call aggregateList f init tl. When that returns, it takes the result and assigns it to rem. Then it calls f on rem and hd.
As other people have pointed out, this does the same thing as the List.foldback function in the basic F# library.
Be careful, of course, to choose the init value properly because if you executed aggregateList mul 0 somelist;; you'll just get 0 no matter what list you supply.
It calls the function f (one of the parameters) giving it the result of the recursive call and the next item.
rem is the remainder, or in this case the result of the remainder of the values.
hd is the next item, as seen in the | hd::tl -> part of the pattern matching.
Effectively this aggregate function takes a function, a starting point, and a list. A way of representing the example line is:
(1 + (2 + (3 + (4 + (5 + 0)))))
Just for fun, let's do some printf style debugging:
> aggregateList (fun acc x -> printf "%i " x; acc + x) 0 [1..10];;
10 9 8 7 6 5 4 3 2 1 val it : int = 55
It looks like the function is equivalent to List.foldBack (or fold_right in other languages): it walks each item in the list from right to left and invokes a function f on them.
Let's re-write the function in a few different ways:
// functional version
let rec foldBack f seed = function
| [] -> seed
| x::xs -> let res = foldBack f seed xs in f res x
// imperative version
let foldBack f seed xs =
let mutable result = seed
for x in List.rev xs do
result <- f result x
result
// C# equivalent
public static U FoldBack<T, U>(Func<T, U> f, U seed, IEnumerable<T> xs) {
foreach(T x in xs.Reverse())
seed = f(seed, x);
return seed;
}
You'd use the function like this:
let sum = foldBack (+) 0 [1..10] // returns 55
let sumOfSquares = foldBack (fun acc x -> acc + x * x) 0 [1..10];; // 385
I don't understand in second branch in
that pattern matching: f rem hd. Could
somebody help me?
So let's start with what we already know about F# functions:
f is a function with the type int -> int -> int. You pass functions around as if they were any other variable like ints or strings.
You call functions by passing a space-separated list of arguments. f rem hd invokes the function f with two arguments, rem and hd.
The last expression evaluated in a function is treated as the function's return value.
So going back to the original function:
let rec aggregateList (f:int->int->int) init list =
match list with
| [] -> init
| hd::tl ->
let rem = aggregateList f init tl // 1
f rem hd // 2
In line 1, we call aggregateList recusively with tl. Since the list gets smaller and smaller, we're eventually going to hit the nil case, which returns init.
In line 2, f rem hd is the function's return value. However, since we recursed down the stack as we made our way to end of the list, we're going to call this function one for each element (in right-to-left order) as we walk back up the stack trace.
Given aggregateList (+) 0 [1..10], the nil case returns 0, so we call:
return value = f rem hd = f 0 10 = 0 + 10 = 10
return value = f rem hd = f 10 9 = 9 + 10 = 19
return value = f rem hd = f 19 8 = 19 + 8 = 27
return value = f rem hd = f 27 7 = 27 + 7 = 34
return value = f rem hd = f 34 6 = 34 + 6 = 40
return value = f rem hd = f 40 5 = 40 + 5 = 45
return value = f rem hd = f 45 4 = 45 + 4 = 49
return value = f rem hd = f 49 3 = 49 + 3 = 52
return value = f rem hd = f 52 2 = 52 + 2 = 54
return value = f rem hd = f 54 1 = 54 + 1 = 55
No more items in the list, so the whole function returns 55.
As you can imagine, the nested calls in aggregateList evaluate like this for a list of length n:
f (f (f (f (f (f (f (f init hdn) hdn-1) hdn-2) hdn-3) ... hd2) hd1) hd0

Resources