Note: Forums will be making significant UX changes to address key usability improvements surrounding search, discoverability and navigation. To learn more about these changes please visit the announcement which can be found HERE.

Answered 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
     
     Answered Has Code

    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!