views:

134

answers:

3

Is there a way to creating an observable from a sequence in F#?

The required behaviour is that an observer subscribing to the resulting observable receives all the values of the sequence one at a time.

Edit: The question can be framed as: Is there an equivalent to Rx.Observable.FromArray([1,2,3]) as shown here in F#?

Edit 2: Thanks everyone. It took me some time to find the answer, only to find that desco has answered already. For the sake of completeness, here is how it works:

//Using the Reactive Framework.
//References to System.CoreEx.dll and System.Reactive.dll are needed.

open System.Linq

let observable = Observable.ToObservable [1..10]
let odds = observable |> Observable.filter (fun i -> i%2=1)
let disp = odds.Subscribe (fun i -> printfn "%d" i)
disp.Dispose ()
A: 

Yoou can try Reactive Extensions. Please refer to the following blog entry which might help you a lot.

http://www.navision-blog.de/2009/10/20/iobservableiobserver-using-the-reactive-framework-with-f/

Alexander Guan
It should, but it doesn't. For somebody whose first .Net language is F#, the community (and Microsoft) makes it surprisingly hard to find how to use these things. You know, what assemblies to load and what modules to open should be a bit easier than that.
Muhammad Alkarouri
+1  A: 

Is System.Linq.Observable.ToObservable(this IEnumerable source) located in System.Reactive.dll the thing your wanted?

desco
+3  A: 

Just in case you wanted to avoid the additional dependency, it is actually quite easy to implement the behavior using F# events and Observable.guard function that I already used in another answer here at StackOverflow.

Here is the implementation together with a brief example:

module Observable = 
  let ofSeq s = 
    let evt = new Event<_>()
    evt.Publish |> Observable.guard (fun o ->
      for n in s do evt.Trigger(n))

[ 1 .. 10 ] |> Observable.ofSeq
            |> Observable.filter (fun n -> n%2 = 0)
            |> Observable.add (printfn "%d")

And for completeness, the implementation of Observable.guard looks like this:

/// Creates an observable that calls the specified function after someone
/// subscribes to it (useful for waiting using 'let!' when we need to start
/// operation after 'let!' attaches handler)
let guard f (e:IObservable<'Args>) =  
  { new IObservable<'Args> with  
      member x.Subscribe(observer) =  
        let rm = e.Subscribe(observer) in f(); rm } 
Tomas Petricek
Thanks a lot. I was actually hoping for something like that.
Muhammad Alkarouri