Here's a link to a nice F#-Rx sample showing how to get a very nice syntax for Reactive Extensions by using F# LINQ computation expressions. (If you know Rx users who haven't yet discovered F#, this might get them interested!)
open System
open System.Linq
open System.Reactive.Linq
type rxBuilder() =
member this.Bind ((xs:'a IObservable), (f:'a -> 'b IObservable)) =
Observable.SelectMany (xs, f)
member this.Delay f = Observable.Defer f
member this.Return x = Observable.Return x
member this.ReturnFrom xs = xs
member this.Combine (xs:'a IObservable, ys: 'a IObservable) =
Observable.Concat (xs, ys)
member this.For (xs : 'a seq, f: 'a -> 'b IObservable) =
Observable.For(xs, new Func<_, IObservable<_>>(f))
member this.TryFinally (xs: 'a IObservable, f : unit -> unit) =
Observable.Finally(xs, new Action(f))
member this.TryWith (xs: 'a IObservable, f: exn -> 'a IObservable) =
Observable.Catch (xs, new Func<exn, 'a IObservable>(f))
member this.While (f, xs: 'a IObservable) =
Observable.While (new Func<bool>(f), xs)
member this.Yield x = Observable.Return x
member this.YieldFrom xs = xs
member this.Zero () = Observable.Empty()
let rx = rxBuilder()
// Rx combinators
let repeat (xs:IObservable<_>) = xs.Repeat()
// Sample usages
let xs = rx { yield 42
yield 43 }
let ys = rx { yield 42
yield! xs }
let zs = rx { for i = 0 to 10 do yield i }
let redTime = rx { while (DateTime.Now.Second > 30) do
yield ConsoleColor.Red }
let blueTime = rx { while (DateTime.Now.Second < 30) do
yield ConsoleColor.Green }
letcoloredTime = rx { yield! redTime
yield! blueTime } |> repeat
This was also recently mentioned on StackOverflow. I think that the code samples are slightly misleading, because they suggest you can use the usual programming style used when working with F# sequences. However, there are quite a few tricky differences – using "let!" may execute the body of the sequence multiple times in parallel and writing an "infinite" recursive loop using "yield!" will eventually give stack overflow exception.
Nevertheless, it is a nice example and it shows quite a few interesting things that can be written using the F# syntax and cannot be directly written using LINQ (e.g. multiple yields).
[1] stackoverflow.com/…/how-do-i-change-the-rx-builder-implementation-to-fix-the-stack-overflow-exception
Hi, after blogging the RxBuilder I discovered the issue with infinite sequences and I post it a question on StackOverflow and Reactive Extensions forum about this.
social.msdn.microsoft.com/…/6cf59ad7-f7e6-4c2e-bf3b-da4f69f22379
As Tomas suggested on StackOverflow in order to make this work we need a special Concat that doesnt blow the stack.
I've been using Rx with C# a lot at work and I think the F# Computation Expression Syntax enables a level of expressiveness that you don't get that easily with C# LINQ.
Since IObservable is the mathematical dual of IEnumerable (as Erik Meijer team discovered) I think it would make a lot of sense for the RxBuilder to be spiced up to provide the same level of power as seq<T>.
Cheers,
HoloEd