Observable from callback method - f#

Let say I have a class which iherits legacy API and overrides a virtual method which is called when something happens
type MyClass() as this =
let somethingObservable: IObservable<Something> = ...
override _.OnSomething(s: Something) = ...
How can I translate each invokation of OnSomething to a notification of somethingObservable?
That's probably a simple question, but I could not find a way to do it properly (should I use not advised ISubject?). Appreciate your help.

Using a subject like this is fine, and ensures correctness in the implementation.
Here's an example using FSharp.Control.Reactive, which gets you the idiomatic way of writing this.
type MyClass() =
inherit Legacy()
let somethingObservable =
Subject.broadcast
override _.OnSomething s =
somethingObservable |> Subject.onNext s |> ignore
member _.AsObservable =
somethingObservable |> Observable.asObservable
You can also use new Subject<_> and its methods, same thing.
In some assembly if you'd prefer not to take on the System.Reactive dependency, F# also natively supports IObservable through events.
type MyClassEvt() =
inherit Legacy()
let event = new Event<_>()
override _.OnSomething s =
event.Trigger s
member _.AsObservable =
event.Publish :> IObservable<_>

Related

type-parametrized overload in F#

when using Microsoft.SqlServer.TransactSql.ScriptDom for parsing, implementation of visitor usually looks like this:
open Microsoft.SqlServer.TransactSql.ScriptDom
let assembly _ =
let refs = ResizeArray()
refs, {
new TSqlFragmentVisitor() with
override this.Visit(s:CreateAssemblyStatement) = refs.Add(s)
}
each such visitor takes 6 LOC, while the only difference is typehint 'CreateAssemblyStatement'
so i tried this:
let visitor<'T> _ =
let refs = ResizeArray<'T>()
refs, {
new TSqlFragmentVisitor() with
override this.Visit(s:'T) = refs.Add(s)
}
let assemblyVisitor = visitor<CreateAssemblyStatement>
let executeVisitor = visitor<ExecuteStatement>
compiler complaints about non-restricted type:
error FS3213: The member 'Visit: 'T -> unit' matches multiple overloads of the same method.
Please restrict it to one of the following:
Visit: TSqlFragment -> unit
Visit: StatementList -> unit
...
adding type constraint did not help (TSqlFragment is base class):
let visitor<'T when 'T :> TSqlFragment> _ =
let refs = ResizeArray<'T>()
refs, {
new TSqlFragmentVisitor() with
override this.Visit(s:'T) = refs.Add(s)
}
so i believe this approach is just impossible, is there any other elegant way how to factor out that typehint?
Unfortunately, this is not going to be possible - and I cannot think of an elegant workaround.
The problem is that the Visit methods of TSqlFramentVisitor are not generic. This is an overloaded Visit method that has a large number of overloads (1031 according to my VS tooltip!) Each of those methods is logically a different method (they happen to have the same name, but they could as well have all different names).
This means that there is no way to compile the generic visitor function - because the compiler would need to decide, when compiling the visitor function, which of the Visit methods to override. Unfortunately, it cannot do this - because it can only decide this when it knows what the type of the method argument is (to choose one of the 1031 methods).
(Another issue is that, if someone defined a new class that inherits from TSqlFragment, this might need to override a method that does not even exist!)

let vs member for private functions, in F#

Let's consider this code:
type TransactionTypes =
| TransactionType1
| TransactionType2
type Test() =
let mutable lastTransactionType1 = DateTime.MinValue
let mutable lastTransactionType2 = DateTime.MinValue
let getLastTransaction transaction =
match transaction with
| TransactionType1 -> lastTransactionType1
| TransactionType2 -> lastTransactionType2
let updateLastTransaction transaction =
match transaction with
| TransactionType1 -> lastTransactionType1 <- DateTime.UtcNow
| TransactionType2 -> lastTransactionType2 <- DateTime.UtcNow
Now (with the understanding that I'm still learning F#), I would like to clarify a couple things:
Something like:
let a = DateTime.Now
does a permanent binding, so 'a' will always be the same time on subsequent uses.
But, my understanding is that if there is a parameter, like:
let a anyParameter = DateTime.Now
will be re-evaluated every time due to the presence of the parameter. Is that correct?
In the code above, the two let statements (getLastTransaction and updateLastTransaction) are private to the type (Test)
I could also have implemented them as:
member private this.getLastTransaction = ...
member private this.updateLastTransaction = ...
Is there any reason, for private functions to prefer let vs. member private this?
"let mutable" already implies the this. so the fields are accessible by both forms.
So, what is the advantage of one form vs. the other?
When you are working with members, F# inherits a lot of things from the .NET object model. A .NET object can have a couple of different things:
Fields - those are storing a value (just like fields of a record). They can be mutable or immutable.
Methods - those can be invoked with zero or more arguments (like functions)
Properties - those have no arguments (like fields); they can be read or written, but when this happens, some code is invoked. A property is basically a pair of getter and setter methods.
In F#, some of this is less visible. However, let corresponds to a field and member with arguments corresponds to a method. Your tricky case is a member without arguments. For example:
type A() =
member x.Foo = printfn "Hi"; 42
Will Hi be printed only once, or will it be printed each time you access Foo? To answer, it's useful to know that Foo is a property with a getter. The above is actually a syntactic sugar for the full version:
type A() =
member x.Foo
with get() = printfn "Hi"; 42
Now you can see that there is a method behind the Foo property! Each time you access Foo, the compiler will generate a call to the get() method, so Hi will be printed repeatedly.
In addition to Tomas' answer:
let mutable lastTransactionType1 = DateTime.MinValue
is equivalent in C# to:
internal DateTime lastTransactionType1 = DateTime.MinValue;
and
member private this.getLastTransaction ...
is the same IL as far as IL is concerned with
let getLastTransaction ...
In equivalent C#, both are
internal DateTime getLastTransactionMember(TransactionTypes transaction)
{
if (transaction.Tag != 1)
{
return lastTransactionType1;
}
return lastTransactionType2;
}
But for using F# in an idiomatic way, you would want to go with let.
There's also a difference in that member does let you use the methods in bindings before their declaration, which might be useful in some cases (read: hacks)
let getType1 = this.getLastTransactionMember TransactionType1 //this compiles
member private this.getLastTransactionMember transaction =
match transaction with
| TransactionType1 -> lastTransactionType1
| TransactionType2 -> lastTransactionType2

f# adding non interface functions to object expressions

Say I have an interface ICache which defines two functions, Function1 and Function2 and I use an object expression to implement it, but I also want to add a helper function:
let WebCache =
{ new ICache with
member __.HelperFunction = //this doesn't work!
member __.Function1 = foo
member __.Function2 = bar
}
F# seems to not allow you to add any methods that are not part of the interface. Is there a workaround? If I want to do this, should I not be using an object expression in the first place?
You can define the helper function as an ordinary (local) function outside of the object expression:
let WebCache =
let helper n =
printfn "Helping %" n
{ new ICache with
member __.Function1 = helper 1
member __.Function2 = helper 2 }

Observable vs FSharpx asyncSeq

I have the following tweet stream class. It has the TweetReceived event which can be used with the other components of my system.
It seems to work ok but I have the feeling that it's more complicated than it should be.
Are there any tools out there to give me this functionality without having to implement the mbox/event mechanism by myself?
Also would you recommend to use asyncSeq instead of IObservable?
Thanks!
type TweetStream ( cfg:oauth.Config) =
let token = TwitterToken.Token (cfg.accessToken,
cfg.accessTokenSecret,
cfg.appKey,
cfg.appSecret)
let stream = new SimpleStream("https://stream.twitter.com/1.1/statuses/sample.json")
let event = new Event<_>()
let agent = MailboxProcessor.Start(fun (mbox) ->
let rec loop () =
async {
let! msg = mbox.Receive()
do event.Trigger(msg)
return! loop()
}
loop ())
member x.TweetReceived = event.Publish
member x.Start () =
Task.Factory.StartNew(fun () -> stream.StartStream(token, agent.Post))
|> ignore
member x.Stop = stream.StopStream
UPDATE:
Thanks Thomas for the quick (as always) answer to the second question.
My first question may be a little unclear so I refactored the code to make the class AgentEvent visible and I rephrase the first question: is there a way to implement the logic in AgentEvent easier? Is this logic implemenented already in some place?
I'm asking this because it feels like a common usage pattern.
type AgentEvent<'t>()=
let event = new Event<'t>()
let agent = MailboxProcessor.Start(fun (mbox) ->
let rec loop () =
async {
let! msg = mbox.Receive()
do event.Trigger(msg)
return! loop()
}
loop ())
member x.Event = event.Publish
member x.Post = agent.Post
type TweetStream ( cfg:oauth.Config) =
let token = TwitterToken.Token (cfg.accessToken,
cfg.accessTokenSecret,
cfg.appKey,
cfg.appSecret)
let stream = new SimpleStream("https://stream.twitter.com/1.1/statuses/sample.json")
let agentEvent = AgentEvent()
member x.TweetReceived = agentEvent.Event
member x.Start () =
Task.Factory.StartNew(fun () -> stream.StartStream(token, agentEvent.Post))
|> ignore
member x.Stop = stream.StopStream
I think that IObservable is the right abstraction for publishing the events. As for processing them, I would use either Reactive Extensions or F# Agents (MailboxProcessor), depending on what you want to do.
Note that F# automatically represents events as IObservable values (actually IEvent, but that inherits from observable), so you can use Reactive Extensions directly on TweetReceived.
What is the right representation?
The main point of asyncSeq is that it lets you control how quickly the data is generated - it is like async in that you have to start it to actually do the work and get a value - so this is useful if you can start some operation (e.g. download next few bytes) to get the next value
IObservable is useful when you have no control over the data source - when it just keeps producing values and you have no way to pause it - this seems more appropriate for tweets.
As for processing, I think that Reactive Extensions are nice when they already implement the operations you need. When you need to write some custom logic (that is not easily expressed in Rx), using Agent is a great way to write your own Rx-like functions.

Setting base member values in F#

I am messing about trying to implement my own basic view engine in F# at the moment. Essentially I am inheriting from the VirtualPathProviderViewEngine.
To do this I need to set two view locations so the engine knows where to look for the views. In my F# type I inherit from the above and try to set the two view locations as below...
type FSharpViewEngine() =
inherit VirtualPathProviderViewEngine()
let viewLocations = [| "~/Views/{1}/{0}.fshtml"; "~/Views/Shared/{0}.fshtml" |]
member this.ViewLocationFormats = viewLocations
member this.PartialViewLocationFormats = viewLocations
The code above omits the overrides that are needed for the VirtualPathProviderViewEngine.
I run the project and I get an error message to say
The property 'ViewLocationFormats' cannot be null or empty.
Which I am assuming means that I am not setting the two base members correctly above. Am I just assigning the above incorrectly or do you suspect I am doing something else wrong?
As extra info, I have added the ViewEngine at start up time in the Global.fs (global.asax) like so...
ViewEngines.Engines.Add(new FSharpViewEngine())
If you just want to set properties of a base class, then you do not need member or override, but instead you need to use the assignment operator <- in the constructor. To implement the engine, you'll need to override two abstract methods that it defines, so you'll need something like this:
type FSharpViewEngine() =
inherit VirtualPathProviderViewEngine()
let viewLocations = [| "~/Views/{1}/{0}.fshtml"; "~/Views/Shared/{0}.fshtml" |]
do base.ViewLocationFormats <- viewLocations
base.PartialViewLocationFormats <- viewLocations
override x.CreatePartialView(ctx, path) = failwith "TODO!"
override x.CreateView(ctx, viewPath, masterPath) = failwith "TODO!"

Resources