How to use Observable.Zip in F# - f#

This is my code in C#
Observable.Zip(ob1, ob2, (a, b) => a + b);
I am trying to convert this to F# using Pipe-Forwarding operator
ob1 |> Observable.Zip(ob2, Func<_,_,_> (fun a b -> a + b))
It won't compile because it can't get which overload I am trying to use.
Any clue ?
The following works just fine, I am just curious if I could make the pipe-forwarding operator work here. Technically it should take ob1 on left hand side as first parameter and take the two supplied parameters as 2nd and 3rd right ?
Observable.Zip (ob1,ob2 ,Func<_,_,_>(fun a b -> a + b))

As mentioned in the comment you can implement a simple wrapper like this:
open System.Reactive.Linq
let zipWith (f : 'T -> 'U -> 'R)
(second: IObservable<'U>)
(first: IObservable<'T>)
: IObservable<'R> =
Observable.Zip(first, second, f)
and with this just do as you wanted:
ob1 |> zipWith (fun a b -> a+b) ob2
PS: it looks even nicer if you do it like this:
ob1 |> zipWith (+) ob2

You seem to have some wrong impressions of how pipe operator works, so I'll try to clear those up.
Let's make things simpler to type out and say we have functions foo and bar:
let foo (a, b, f) = f a b
let bar a b f = f a b
foo has more or less the same shape as Observable.Zip and takes a tuple as an argument (this is how C# functions are seen in F#), bar is the same but is curried.
This works:
foo (ob1, ob2, fun a b -> a + b)
bar ob1 ob2 (fun a b -> a + b)
This doesn't work:
ob1 |> bar ob2 (fun a b -> a + b)
That's because what pipe operator does, is taking the value on the left, and passing it as the last argument to the function on the right. You'd need bar to be defined like this:
let bar b f a = f a b
That's why the functions in for example the List module are defined in a way that the actual list is passed in as the last argument - that makes pipelining work in a nice way.
This also doesn't work:
ob1 |> foo (ob2, fun a b -> a + b)
Apart from the previous problem, it would also require pipe operator to look inside a tuple and attach a value there, and that's really not how it works. A tuple is a single value in F#. The function that would work for that example would be this one:
let foo (b, f) a = f a b
But clearly that's not what we want.
You can still use Observable.Zip in a pipeline fashion like this:
ob1 |> fun x -> Observable.Zip(x, ob2, Func<_,_,_> (fun a b -> a + b))
Or simply go with the wrapper the other answer suggests.

Related

F# pipe operator confusion

I am learning F# and the use cases of the |>, >>, and << operators confuse me. I get that everything if statements, functions, etc. act like variables but how do these work?
Usually we (community) say the Pipe Operator |> is just a way, to write the last argument of a function before the function call. For example
f x y
can be written
y |> f x
but for correctness, this is not true. It just pass the next argument to a function. So you could even write.
y |> (x |> f)
All of this, and all other kind of operators works, because in F# all functions are curried by default. This means, there exists only functions with one argument. Functions with many arguments, are implemented that a functions return another function.
You could also write
(f x) y
for example. The function f is a function that takes x as argument and returns another function. This then gets y passed as an argument.
This process is automatically done by the language. So if you write
let f x y z = x + y + z
it is the same as:
let f = fun x -> fun y -> fun z -> x + y + z
Currying is by the way the reason why parenthesis in a ML-like language are not enforced compared to a LISP like language. Otherwise you would have needded to write:
(((f 1) 2) 3)
to execute a function f with three arguments.
The pipe operator itself is just another function, it is defined as
let (|>) x f = f x
It takes a value x as its first argument. And a function f as its second argument. Because operators a written "infix" (this means between two operands) instead of "prefix" (before arguments, the normal way), this means its left argument to the operator is the first argument.
In my opinion, |> is used too much by most F# people. It makes sense to use piping if you have a chain of operations, one after another. Typically for example if you have multiple list operations.
Let's say, you want to square all numbers in a list and then filter only the even ones. Without piping you would write.
List.filter isEven (List.map square [1..10])
Here the second argument to List.filter is a list that is returned by List.map. You can also write it as
List.map square [1..10]
|> List.filter isEven
Piping is Function application, this means, you will execute/run a function, so it computes and returns a value as its result.
In the above example List.map is first executed, and the result is passed to List.filter. That's true with piping and without piping. But sometimes, you want to create another function, instead of executing/running a function. Let's say you want to create a function, from the above. The two versions you could write are
let evenSquares xs = List.filter isEven (List.map square xs)
let evenSquares xs = List.map square xs |> List.filter isEven
You could also write it as function composition.
let evenSquares = List.filter isEven << List.map square
let evenSquares = List.map square >> List.filter isEven
The << operator resembles function composition in the "normal" way, how you would write a function with parenthesis. And >> is the "backwards" compositon, how it would be written with |>.
The F# documentation writes it the other way, what is backward and forward. But i think the F# language creators are wrong.
The function composition operators are defined as:
let (<<) f g x = f (g x)
let (>>) f g x = g (f x)
As you see, the operator has technically three arguments. But remember currying. When you write f << g, then the result is another functions, that expects the last argument x. Passing less arguments then needed is also often called Partial Application.
Function composition is less often used in F#, because the compiler sometimes have problems with type inference if the function arguments are generic.
Theoretically you could write a program without ever defining a variable, just through function composition. This is also named Point-Free style.
I would not recommend it, it often makes code harder to read and/or understand. But it is sometimes used if you want to pass a function to another
Higher-Order function. This means, a functions that take another function as an argument. Like List.map, List.filter and so on.
Pipes and composition operators have simple definition but are difficult to grasp. But once we have understand them, they are super useful and we miss them when we get back to C#.
Here some explanations but you get the best feedbacks from your own experiments. Have fun!
Pipe right operator |>
val |> fn ≡ fn val
Utility:
Building a pipeline, to chain calls to functions: x |> f |> g ≡ g (f x).
Easier to read: just follow the data flow
No intermediary variables
Natural language in english: Subject Verb.
It's regular in object-oriented code : myObject.do()
In F#, the "subject" is usually the last parameter: List.map f list. Using |>, we get back the natural "Subject Verb" order: list |> List.map f
Final benefit but not the least: help type inference:
let items = ["a"; "bb"; "ccc"]
let longestKo = List.maxBy (fun x -> x.Length) items // ❌ Error FS0072
// ~~~~~~~~
let longest = items |> List.maxBy (fun x -> x.Length) // ✅ return "ccc"
Pipe left operator <|
fn <| expression ≡ fn (expression)
Less used than |>
✅ Small benefit: avoiding parentheses
❌ Major drawback: inverse of the english natural "left to right" reading order and inverse of execution order (because of left-associativity)
printf "%i" 1+2 // 💥 Error
printf "%i" (1+2) // With parentheses
printf "%i" <| 1+2 // With pipe left
What about this kind of expression: x |> fn <| y ❓
In theory, allow using fn in infix position, equivalent of fn x y
In practice, it can be very confusing for some readers not used to it.
👉 It's probably better to avoid using <|
Forward composition operator >>
Binary operator placed between 2 functions:
f >> g ≡ fun x -> g (f x) ≡ fun x -> x |> f |> g
Result of the 1st function is used as argument for the 2nd function
→ types must match: f: 'T -> 'U and g: 'U -> 'V → f >> g :'T -> 'V
let add1 x = x + 1
let times2 x = x * 2
let add1Times2 x = times2(add1 x) // 😕 Style explicit but heavy
let add1Times2' = add1 >> times2 // 👍 Style concise
Backward composition operator <<
f >> g ≡ g << f
Less used than >>, except to get terms in english order:
let even x = x % 2 = 0
// even not 😕
let odd x = x |> even |> not
// "not even" is easier to read 👍
let odd = not << even
☝ Note: << is the mathematical function composition ∘: g ∘ f ≡ fun x -> g (f x) ≡ g << f.
It's confusing in F# because it's >> that is usually called the "composition operator" ("forward" being usually omitted).
On the other hand, the symbols used for these operators are super useful to remember the order of execution of the functions: f >> g means apply f then apply g. Even if argument is implicit, we get the data flow direction:
>> : from left to right → f >> g ≡ fun x -> x |> f |> g
<< : from right to left → f << g ≡ fun x -> f <| (g <| x)
(Edited after good advices from David)

Composing 2 (or n) ('a -> unit) functions with same arg type

Is there some form of built-in / term I don't know that kinda-but-its-different 'composes' two 'a -> unit functions to yield a single one; e.g.:
let project event =
event |> logDirections
event |> stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project
might become:
let project = logDirections FOLLOWEDBY stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project
and then:
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter (logDirections FOLLOWEDBY stashDirections)
I guess one might compare it to tee (as alluded to in FSFFAP's Railway Oriented Programming series).
(it needs to pass the same arg to both and I'm seeking to run them sequentially without any exception handling trickery concerns etc.)
(I know I can do let project fs arg = fs |> Seq.iter (fun f -> f arg) but am wondering if there is something built-in and/or some form of composition lib I'm not aware of)
The apply function from Klark is the most straightforward way to solve the problem.
If you want to dig deeper and understand the concept more generally, then you can say that you are lifting the sequential composition operation from working on values to work on functions.
First of all, the ; construct in F# can be viewed as sequential composition operator. Sadly, you cannot quite use it as one, e.g. (;) (because it is special and lazy in the second argument) but we can define our own operator instead to explore the idea:
let ($) a b = a; b
So, printfn "hi" $ 1 is now a sequential composition of a side-effecting operation and some expression that evaluates to 1 and it does the same thing as printfn "hi"; 1.
The next step is to define a lifting operation that turns a binary operator working on values to a binary operator working on functions:
let lift op g h = (fun a -> op (g a) (h a))
Rather than writing e.g. fun x -> foo x + bar x, you can now write lift (+) foo bar. So you have a point-free way of writing the same thing - just using operation that works on functions.
Now you can achieve what you want using the lift function and the sequential composition operator:
let seq2 a b = lift ($) a b
let seq3 a b c = lift ($) (lift ($) a b) c
let seqN l = Seq.reduce (lift ($)) l
The seq2 and seq3 functions compose just two operations, while seqN does the same thing as Klark's apply function.
It should be said that I'm writing this answer not because I think it is useful to implement things in F# in this way, but as you mentioned railway oriented programming and asked for deeper concepts behind this, it is interesting to see how things can be composed in functional languages.
Can you just apply an array of functions to a given data?
E.g. you can define:
let apply (arg:'a) (fs:(('a->unit) seq)) = fs |> Seq.iter (fun f -> f arg)
Then you will be able to do something like this:
apply 1 [(fun x -> printfn "%d" (x + 1)); (fun y -> printfn "%d" (y + 2))]

Understanding the F# Composition Operators

I am well-versed in using the >> and << operators in F#. However, after looking in the F# source to establish a deeper understanding I became confused with this:
let inline (>>) f g x = g(f x)
let inline (<<) f g x = f(g x)
How do I interpret these expressions conceptually? Also, how would you describe these expressions? Are they defining a type?
I think the best way to describe it is with an example, as looking at the definition can be a little confusing. Let's say you had this:
let isEven x = x % 2 = 0
[1 .. 99] |> List.filter (fun x -> not (isEven x))
Using the composition operators you could rewrite it as one of these instead:
[1 .. 99] |> List.filter (isEven >> not)
[1 .. 99] |> List.filter (not << isEven)
More genericly, if you have something like this:
data |> a |> b |> c
You can rewrite it like this:
data |> (a >> b >> c)
and interpret a >> b >> c as do a, then do b, then do c. If you prefer the more traditional backwards ordering:
(a (b (c data)))
you can rewrite it as
((a << b << c) data)
This is also called the point free style. In normal cases it can be harder to read than using the normal style, but when passing to higher-order functions, it can be easier to read as you avoid having to add the (fun x -> ) noise.
As the msdn page for F# functions says, "Functions in F# can be composed from other functions. The composition of two functions function1 and function2 is another function that represents the application of function1 followed the application of function2."
It can be thought of as similar to the pipe operators, just without specifying the last/deepest parameter; e.g. the following two lines are equivalent:
let composed = f >> g
let piped x = g <| f x
Also see this question for more information.

Is there a library function or operator to create a tuple?

Given a string of digits, I would like to have a sequence of tuples mapping the non-zero characters with their position in the string. Example:
IN: "000140201"
OUT: { (3, '1'); (4, '4'); (6, '2'); (8, '1') }
Solution:
let tuples = source
|> Seq.mapi (fun i -> fun c -> (i, c))
|> Seq.filter (snd >> (<>) '0')
It seems like (fun i -> fun c -> (i, c)) is a lot more typing than it should be for such a simple and presumably common operation. It's easy to declare the necessary function:
let makeTuple a b = (a, b)
let tuples2 = source
|> Seq.mapi makeTuple
|> Seq.filter (snd >> (<>) '0')
But it seems to me that if the library provides the snd function, it should also provide the makeTuple function (and probably with a shorter name), or at least it should be relatively easy to compose. I couldn't find it; am I missing something? I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.
But it seems to me that if the library provides the snd function, it should also provide the makeTuple function.
F# assumes that you decompose tuples (using fst, snd) much more often than composing them. Functional library design often follows minimal principle. Just provide functions for common use cases, other functions should be easy to define.
I couldn't find it; am I missing something?
No, you aren't. It's the same reason that FSharpPlus has defined tuple2, tuple3, etc. Here are utility functions straight from Operators:
/// Creates a pair
let inline tuple2 a b = a,b
/// Creates a 3-tuple
let inline tuple3 a b c = a,b,c
/// Creates a 4-tuple
let inline tuple4 a b c d = a,b,c,d
/// Creates a 5-tuple
let inline tuple5 a b c d e = a,b,c,d,e
/// Creates a 6-tuple
let inline tuple6 a b c d e f = a,b,c,d,e,f
I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.
F# compiler hides properties of System.Tuple<'T1, 'T2> to enforce pattern matching idiom on tuples. See Extension methods for F# tuples for more details.
That said, point-free style is not always recommended in F#. If you like point-free, you have to do a bit of heavy lifting yourself.
The #pad's answer is great, just to add my 2 cents: I am using similar operator
let inline (-&-) a b = (a, b)
and it looks very convenient to write let x = a -&- b
Maybe you'll find this operator useful too

Tacit programming style using F#

It's not a practically important issue, but I'd like to see an example of tacit programming in F# where my point-free functions can have multiple arguments (not in form of a list or tuple).
And secondly, how such functions can manipulate a complex data structure. I'm trying it out in F# Interactive, but have no success yet.
I tried, for instance:
> (fun _ -> (fun _ -> (+))) 333 222 111 555
Is that right way?
And:
> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";;
val it : string = "cd"
F# doesn't contain some of the basic functions that are available in Haskell (mainly because F# programmers usually prefer the explicit style of programming and use pointfree style only in the most obvious cases, where it doesn't hurt readability).
However you can define a few basic combinators like this:
// turns curried function into non-curried function and back
let curry f (a, b) = f a b
let uncurry f a b = f (a, b)
// applies the function to the first/second element of a tuple
let first f (a, b) = (f a, b)
let second f (a, b) = (a, f b)
Now you can implement the function to add lengths of two strings using combinators as follows:
let addLengths =
uncurry (( (first String.length) >> (second String.length) ) >> (curry (+)))
This constructs two functions that apply String.length to first/second element of a tuple, then composes them and then adds the elements of the tuple using +. The whole thing is wrapped in uncurry, so you get a function of type string -> string -> int.
In F#, the arity of functions is fixed, so you're not going to be able to write both
(op) 1 2
and
(op) 1 2 3 4
for any given operator op. You will need to use a list or other data structure if that's what you want. If you're just trying to avoid named variables, you can always do "1 + 2 + 3 + 4". The most idiomatic way to add a list of numbers in F# is List.sum [1;2;3;4], which also avoids variables.

Resources