F# RX Sum of 1 to 100 code sample - f#

I am learning RX (Reactive Extensions), I tried to use some code samples from internet, the source code was in C#:
var input = Observable.Range(1, 100);
input.Sum().Subscribe(x => Console.WriteLine("The Sum is {0}", x));
Since I don't really "SPEAK" C#, so I want to use F# to do the same thing.
I download RX, and create a F# windows application, add reference to System.Reactive. My IDE is VS 2010 Ultimate, RX version is: 1.1.11111
Here is my code:
#light
open System
open System.Collections.Generic
open System.ComponentModel
open System.Linq
open System.Text
open System.Reactive
open System.Reactive.Linq
let input = Observable.Range(1, 100)
let x = input.Sum().Subscribe()
printfn "%A" x
The result should be 5050, as the sum of 1 to 100 is 5050. However, I can see only this:
System.Reactive.AutoDetachObserver`1[System.Int32]
Please let me know how I can see the result for 5050.
I hope the C# code will work in F# too. If not, please let me know what I can do.
Thanks and Happy New Year to you all!

The Subscribe method takes a function as its argument (x => foo is an anonymous function (lambda expression) in C#). So you should also call it with a function as its argument:
let input = Observable.Range(1, 100)
input.Sum().Subscribe(fun x -> printfn "%A" x)
Or
let input = Observable.Range(1, 100)
input.Sum().Subscribe(printfn "%A")

Related

How to convert between Rx 1 Observable and F# 3 observable?

I'm limited to .net 3.5 and want to use Reactive Extensions with F# 3.0.
Apparently, F# and RX introduce different versions of System.IObservable<T>
open System.Reactive
open System.Timers
open System
[<EntryPoint>]
let main argv =
let timer = new Timer(500.0)
timer.AutoReset <- true
timer.Start()
timer.Elapsed
|> Observable.scan (fun i _ -> i + 1) (-1)
:> IObservable<int>
|> ignore
0
This fails with:
The type 'System.IObservable' is not compatible with the type 'System.IObservable'
Is it possible to use both? Or is there a version of RX compatible with .net 3.5 without conflicts? I also tried looking for sources of rx 1, but didn't find, although I'm not sure if it will be useful

How can I convert an F# (double -> double) to Func<double, double>?

I'm using MathNet.Numerics.LinearAlgebra to build a library. I need to apply a user-specified function to every element of the matrix, for which I know I can use Map:
open System
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Double
let m1 = matrix [[1.0; 2.0; 3.0]]
let f1 = fun s -> s * 3.14
let m2 = m1.Map f1 // THIS FAILS
let m3 = m1.Map (fun s -> s * 3.14) // THIS WORKS!
In the line for m2 I get the following error:
This expression was expected to have type Func<float, 'a> but here has type double -> double
But I need to be able to pass in the mapping function instead of defining it inline as for m3. The documentation for MathNet.Numerics does not seem to have an answer to my problem.
The F# extensions (MathNet.Numerics.FSharp package) usually provide a variant that can handle normal F# functions. In this case, you can write:
let m2 = m1 |> Matrix.map f1
You can construct the delegate like this:
let m2 = m1.Map (Func<_, _> f1)
F# implicitly constructs delegates in some cases, as seen with the lambda in the question, but it's not always seamless. See the MSDN page for delegates in F# for some additional information.

How to pass a "Function" type in FunScript?

I am encountering this Function type that I need to pass to a JQueryAnimationOptions object. I usually would pass a lambda to callbacks but these seem to be incompatible. I looked up every sample I could find in the FunScript repo. and couldn't find any workaround.
It also said the the Function is actually an interface (for what?) when used as a return statement Error: Invalid use of interface type.
So how to pass a callback argument with this Function type?
the code:
[<FunScript.JS>]
module Main
open FunScript
open FunScript.TypeScript
let sayHelloFrom (name:string) =
Globals.window.alert("Hello, " + name)
let jQuery (selector:string) = Globals.jQuery.Invoke selector
let main() =
let options = createEmpty<JQueryAnimationOptions>()
options.duration <- 3000
options.complete <- (fun _ -> sayHelloFrom("F#"))
let properties = createEmpty<Object>()
properties.Item("opacity") <- 1
let mainContent = jQuery "#mainContent"
mainContent.animate(properties, options) |> ignore
mainContent.click(fun e -> sayHelloFrom("F#") :> obj)
This works more or less as you would expect when passing lambdas between F# and C#. In F#, functions can be curried, while in C# (and JavaScript) cannot. So when you need to send a lambda from F# to C# you need to convert it first. In F# this is done by wrapping the lambda like this:
open System.Linq
open System.Collections.Generic
let ar = [|1;2;3|]
let f = fun (x: int) (y: int) -> x + y
let acc = ar.Aggregate( System.Func<int,int,int>(f) )
Actually, the F# compiler can deduce the types most of the times, so you only need to write: System.Func<_,_,_>(f). Furthermore, when passing a F# lambda to a method expecting a C# lambda, the compiler makes the wrapping automatically for you. Then the previous example becomes:
let ar = [|1;2;3|]
let acc = ar.Aggregate( fun x y -> x + y )
(Of course, in this case it would be better to use the idiomatic Array.reduce. This is just a contrived example.)
This works exactly the same when interacting with JS using FunScript. The only thing you need to be aware of is how F# lambdas get translated to JS. To allow currying, a lambda with two or more parameters like fun x y -> x + y becomes:
function (x) {
return function (y) {
return x + y;
}
}
Which may be a problem because the native JS will expect the following signature: function (x, y). In that case, you would have to wrap the lambda with System.Func<_,_,_>() as when interacting with C# (remember this is done automatically if you pass the lambda to a method).
However, lambdas with just one parameter don't suppose any problem: fun x -> x*x becomes function (x) { return x*x; }. In that case you don't need to wrap them (it doesn't hurt to do it anyway) and it's enough just to use unbox to appease the F# compiler when necessary. Just please be aware the FunScript compiler ignores unbox in the final JS code so there'll be no type check at all at runtime.
I hope the explanation is clear. Please add a comment if it isn't and I'll edit the answer.
Nevermind , I found the solution, I had to unbox the lambda:
options.complete <- unbox<Function> (fun _ -> sayHelloFrom("F#"))

F# RX Projection [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
Want to convert some C# code for RX to F# code.
The following C# code works well:
var seqNum = Observable.Range(1, 5);
var seqString = from n in seqNum
select new string('*', (int)n);
seqString.Subscribe(str => { Console.WriteLine(str); });
Console.ReadKey();
The following is my code in F#:
#light
open System
open System.Collections.Generic
open System.Linq
open System.Reactive
open System.Reactive.Linq
open System.Reactive.Subjects
open System.Threading
open System.IO
let seqNum = Observable.Range(1, 5)
let seqString = from n in seqNum
select new string('*', (int)n)
Console.ReadLine() |> ignore
But I got the following compiler error:
Error: Unexpected keyword 'new' in implementation file
If I deleted the new keyword, I got another error:
Error: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized
The "new" keyword are totally different in C# and F#.
Please show me how to do the same job in F#.
Thanks,
In C# string is the shortcut to System.String class. However, in F# string is a function which has obj as its input and returns a string which is overriden in obj.ToString():
let s = string('*', 3);; // tuple to string
// val s : string = "(*, 3)"
What you really want is creating a string by repeating '*' three times:
let s = new String('*', 3)
// val a : String = "***"
To be clear, from ... in ... select ... is C# LINQ syntax which is invalid in F#. Therefore, using computation expression instead:
let seqNum = seq {1..5}
let seqString = seq { for n in seqNum -> new String('*', n) }
To get some ideas of creating/using computation expression for Reactive Extension, take a look at the question and its answers at How do I change the Rx Builder implementation to fix the stack overflow exception?
Instead of using the String constructor use the String.replicate method.
String.replicate n "*"
There is no direct equivalent for String(char, int) but String.replicate: int -> string -> string is roughly the equivalent with string instead of char
F# version for that code
[1 .. 5]
|> Seq.map (fun i -> String.replicate i "*")
Here you go:
open System
open System.IO
open System.Reactive
open System.Reactive.Linq
let seqString = Observable.Range(1,5).Select(fun x -> String.replicate x "*")
using (seqString.Subscribe (fun x -> printfn "%s" x))
(fun _ -> Console.ReadLine() ) |> ignore
EDIT: As Paul suggested below two last lines can be replaced by simple
seqString.Subscribe (printfn "%s") |> ignore
However, if we want to gracefully unsubscribe from our subscription, but get rid of using in lieu of newer use syntax we may replace last two lines by the following three
do
use subscription = seqString.Subscribe(printfn "%s")
Console.ReadLine() |> ignore

Obserable take select conversion

I am learning RX (Reactive Extensions), I tried to use some code samples from internet, the source code was in C#:
var input = new[] {1,2,3,4,5,4}.ToObservable();
var output = input.Take(5).Select(x => x * 10);
output.Dump();
I want to use F# to do the same thing. I download RX, and create a F# windows application, add reference to System.Reactive. My IDE is VS 2010 Ultimate, RX version is: 1.1.11111 Here is my code:
#light
open System
open System.Collections.Generic
open System.Linq
open System.Reactive
open System.Reactive.Linq
let input = [1; 2; 3; 4; 5; 4].ToObservable()
let output = input.Take(5).Select(fun x -> printfn "%A" x)
printfn "%A" output
printfn "Done"
I believe it is an easy job, however, in my IDE, neither C# nor F# gave any useful information. Besides, there is no output.Dump() I can use in C# or in F#.
The lambda expression in F# didn't show any information.
The printfn "%A" output showed this information:
System.Reactive.Linq.Observable+SelectObservable`2[System.Int32,Microsoft.FSharp
.Core.Unit]
Let me know if I miss something or if my code is wrong.
Thanks and happy new year to you all!
You should learn about Observables more. You have to subscribe to the observable collection. Also you should not make side-effects in Select method. So the code should look like this:
use xs = [1; 2; 3; 4; 5; 4].ToObservable().Take(5).Subscribe(printfn "%A")
Not sure why you want to do this, but this produces the result you expect.
let input = [1; 2; 3; 4; 5; 4].ToObservable()
let output = input.Take(5).ToEnumerable()
printfn "%A" output
All this does is convert a #seq<int> to IObservable<int> and back again. I suppose it would be more meaningful if you chained some additional transformations prior to calling ToEnumerable.

Resources