How to use FSharp.reactive
-
Saturday, May 12, 2012 8:17 PM
Hello,
I am learning RX, but I don’t know much about C#, since most my program is in F#, so I want to see if I can first try to convert some basic C# RX code to F#.
The following code from internet works for C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
namespace SimpleSequence
{
class Program
{
static void Main(string[] args)
{
IObservable<int> source = Observable.Range(1, 10);
IDisposable subscription = source.Subscribe(
x => Console.WriteLine("OnNext: {0}", x),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted"));
Console.WriteLine("Press ENTER to unsubscribe...");
Console.ReadLine();
subscription.Dispose();
}
}
}
However, when I try to convert the above code into F#, I have a lot of headache.
I have tried to install FSharp.reactive from https://github.com/panesofglass/FSharp.Reactive
I download the software and compile it, it works, then I reference the compiled FSharp.Reactive.dll;
FSharp.Reactive.Linq.dll; FSharp.Reactive.Interfaces.dll; FSharp.Reactive.core.dll;
But I can not get my code compiled:
#light
open System
open System.Collections.Generic
open System.Linq
open System.Text
open System.Reactive
open System.Reactive.Linq
open System.Reactive.Subjects
let source = Observable.Range(1,10)
let subscription = source.Subscribe(fun x -> printfn "%d", x)
I got some compiler error:
Error No overloads match for method 'Subscribe'.
I think I don’t have an idea how to make FSharp.reactive to recognize the Subscribe method.
Since there is no code sample for using FSharp.reactive or other RX for F#, so it is difficult for me to figure it out. My development environment: Visual Studio 11 Beta!
Any help is greatly appreciated!
Thanks,
John
- Edited by zydjohn Saturday, May 12, 2012 8:21 PM
All Replies
-
Monday, May 14, 2012 12:11 PM
Unfortunately I think this might be a touch embarrassing. Just use this instead:
let sub = source.Subscribe(fun x -> printfn "%d" x)
The `Subscribe` method takes a single parameter, being the action to perform. F# functions don't need commas between them (except when they are tuple parameters, which isn't the case here and they would need to be surrounded with braces here anyway).
When you write the lambda function with a comma, it treats it as two parameters to Subscribe, and no such overload exists.
- Marked As Answer by zydjohn Monday, May 14, 2012 7:24 PM
-
Monday, May 14, 2012 7:26 PM
Hello,
Thank you very much, I modified the code, even I got the compiler error:
Error internal error: The lists had different lengths. Parameter name: xs2 (ArgumentException)
But I run the code, it works.
However, according to the C# code, I still want to see if I can convert the other parts of subscribe method, as there are still OnError and OnCompleted parts which I don’t know how to implement in F#, so I changed my code, so it is as below, but I can not get it compiled:
let subscription = source.Subscribe(fun x -> printfn "%d" x, fun y -> printfn "%A" y, fun z -> printfn "Done")
I got 4 compiler errors:
Error 1: Possible overload: 'IObservable.Subscribe<'TSource>(onNext: Action<'TSource>) : IDisposable'. Type constraint mismatch. The type 'b -> unit * ('c -> unit * ('d -> unit)) is not compatible with type 'a -> unit The type 'unit' does not match the type 'unit * ('a -> unit * ('b -> unit))'.
Error 2: Possible overload: 'member IObservable.Subscribe : callback:('T -> unit) -> IDisposable'. Type constraint mismatch. The type 'a -> unit * ('b -> unit * ('c -> unit)) is not compatible with type int -> unit The type 'unit' does not match the type 'unit * ('a -> unit * ('b -> unit))'.
Error 3: No overloads match for method 'Subscribe'. The available overloads are shown below (or in the Error List window).
Error 4: Possible overload: 'IObservable.Subscribe(observer: IObserver<int>) : IDisposable'. Type constraint mismatch. The type 'a -> unit * ('b -> unit * ('c -> unit)) is not compatible with type IObserver<int> The type ''a -> unit * ('b -> unit * ('c -> unit))' is not compatible with the type 'IObserver<int>'.
I think it is basic requirements for RX, at least in C#, it is straightforward, but why it is not easy in F#.
Any idea is welcome!

