F# has a rather nice syntax for events, which can be subscribed to as observables without any custom code for that purpose. I am creating an event that publishes updates to a member variable. I intend to subscribe to this event as an observable, but I want the existing value (which I know exists) to be pushed on subscription. Is this possible and simple to do with the event syntax, or do I need to create a proper observable using e.g. BehaviorSubject?
This depends a lot on how you plan to use it.
When you convert from an event to an observable, the EventArgs are mapped through as the observable's type. With a "standard" event, this won't have a value (EventArgs doesn't carry any information).
However, you can easily use a custom event type, or event violate normal .NET guidelines for events and use the value itself:
let evt = Event<int>()
let obs = evt.Publish :> IObservable<_>
obs |> Observable.add (fun v -> printfn "New value: %d" v)
evt.Trigger 3
evt.Trigger 4
That being said, depending on your use case, you may want to look at Gjallarhorn. This library was specifically designed for tracking changes to mutable values and signaling nicely. It's built around the concept of a "signal", which is an observable that contains a current value. This makes the above concept first class - you can pass something (a signal) that can directly be used as an IObservable whenever needed, but also can always be used to get the underlying, current value. In practice, this dramatically simplifies many use cases.
Related
I have a type that receives data through websocket / event and it instantiates a couple other types that also need that data for their work.
I thought it would simplify the code to have only one event listener, in the parent type and pass the result by reference so the children types could access the last data.
I've never used byref in F# and .. looks like I don't get it right
From the parent:
let mutable lastTrade = TradeData.empty // this gets updated through an event
let closeOrderHandler = CloseOrderHandler(coreGuid, instrument, &lastTrade)
and the child object:
type CloseOrderHandler(coreGuid: string, instrument: Instrument, lastTrade: byref<TradeData>) = ...
but this will not compile, I get:
[FS0412] A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
what am I doing wrong?
What I am trying to accomplish is to have one mutable field with results updated by a socket / event and the child types be able to read the last result as they need (their actions are event driven, so they don't always get called from the parent and need to access the latest value as they need).
I've read about Reader Monad from this article by Jorge Castillo himself and I've also got this article by Paco. It seems that both tackles the idea of Dependency Injection just in a different way. (Or am I wrong?)
I'm really confused whether I understand the whole Reader Monad and how it relates to the Simple Depenency Injection that Paco is talking about.
Can anyone help me understand these two things? Would I ever need both of them in one project depending on situations?
Your doubt is understandable, since yes both approaches share the same outcome: Passing dependencies implicitly for you all the way across your call stack, so you don't need to pass them explicitly at every level. With both approaches you will pass your dependencies once from the outer edge, and that's it.
Let's say you have the functions a(), b(), c() and d(), and let's say each one calls the next one: a() -> b() -> c() -> d(). That is our program.
If you didn't use any of the mentioned mechanisms, and you needed some dependencies in d(), you would end up forwarding your dependencies (let's call them ctx) all the way down on every single level:
a(ctx) -> b(ctx) -> c(ctx) -> d(ctx)
While after using any of the mentioned two approaches, it'd be like:
a(ctx) -> b() -> c() -> d()
But still, and this is the important thing to remember, you'd have your dependencies accessible in the scope of each one of those functions. This is possible because with the described approaches you enable an enclosing context that automatically forwards them on every level, and that each one of the functions runs within. So, being into that context, the function gets visibility of those dependencies.
Reader: It's a data type. I encourage you to read and try to understand this glossary where data types are explained, since the difference between both approaches requires understanding what type classes and data types are, and how they play together:
https://arrow-kt.io/docs/patterns/glossary/
As a summary, data types represent a context for the program's data. In this case, Reader stands for a computation that requires some dependencies to run. I.e. a computation like (D) -> A. Thanks to it's flatMap / map / and other of its functions and how they are encoded, D will be passed implicitly on every level, and since you will define every one of your program functions as a Reader, you will always be operating within the Reader context hence get access to the required dependencies (ctx). I.e:
a(): Reader<D, A>
b(): Reader<D, A>
c(): Reader<D, A>
d(): Reader<D, A>
So chaining them with the Reader available combinators like flatMap or map you'll get D being implicitly passed all the way down and enabled (accessible) for each of those levels.
In the other hand, the approach described by Paco's post looks different, but ends up achieving the same. This approach is about leveraging Kotlin extension functions, since by defining a program to work over a receiver type (let's call it Context) at all levels will mean every level will have access to the mentioned context and its properties. I.e:
Context.a()
Context.b()
Context.c()
Context.d()
Note that an extension function receiver is a parameter that without extension function support you'd need to manually pass as an additional function argument on every call, so in that way is a dependency, or a "context" that the function requires to run. Understanding those this way and understanding how Kotlin interprets extension functions, the receiver will not need to be forwarded manually on every level but just passed to the entry edge:
ctx.a() -> b() -> c() -> d()
B, c, and d would be called implicitly without the need for you to explicitly call each level function over the receiver since each function is already running inside that context, hence it has access to its properties (dependencies) enabled automatically.
So once we understand both we'd need to pick one, or any other DI approach. That's quite subjective, since in the functional world there are also other alternatives for injecting dependencies like the tagless final approach which relies on type classes and their compile time resolution, or the EnvIO which is still not available in Arrow but will be soon (or an equivalent alternative). But I don't want to get you more confused here. In my opinion the Reader is a bit "noisy" in combination with other common data types like IO, and I usually aim for tagless final approaches, since those allow to keep program constraints determined by injected type classes and rely on IO runtime for the complete your program.
Hopefully this helped a bit, otherwise feel free to ask again and we'll be back to answer 👍
I have a C# WebAPI application that uses an F# library.
The F# library has a value:
let mutable CurrentCustomer:Customer option = None
I also have:
let Customers:Map<string,Customer> option = None
Both Customers and Customer are "global variables". On start-up the C# application loads a collection of customers into this global variable Customers. Then I have a customersController that has a Post, which calls an F# function setCurrentCustomer that sets the global variable CurrentCustomer from the collection stored in Customers:
// Post in customersController:
public HttpResponseMessage Post(string identifier)
{
var _customer = FSharpLibrary.setCurrentCustomer(identifier);
// code
}
// setCurrentCustomer function:
let mutable CurrentCustomer:Customer option = None
let setCurrentCustomer() =
CurrentCustomer <- customer |> Some
CurrentCustomer
Is there any way to avoid changing state by changing CurrentCustomer?
I know I could create a function that takes a CurrentCustomer object and returns a new CurrentCustomer object, but how will the customersController know what is the current customer set to?
Is there any way of avoiding having this global mutable variable Customer?
Is there any way to avoid changing state by changing CurrentCustomer?
Yes, there are many ways to do that, but most will involve changing the design of your FSharpLibrary so that it doesn't rely on mutable state.
As a completely general answer, you could apply the State Monad, but something less involved is often sufficient. Exactly what that would be, however, is impossible to answer without knowing what you are attempting to accomplish.
how will the customersController know what is the current customer set to?
It already knows, because it's setting the current customer to the identifier argument from the Post method. That value is in scope throughout the entire method.
The question is why your FSharpLibrary has mutable state? Can't you instead implement it with pure functions?
Where is it gone ?
let triggerFindNext,findNextEvent = IEvent.create<EventArgs>()
The field, constructor or member 'create' is not defined
maybe I must to add some Framework for it ?
The IEvent.create function has been deprecated. A new way of creating events is to create instance of the Event type. In the simplest case you can write just this:
let evt = new Event<EventArgs>()
// Trigger event (instead of first element of the tuple)
evt.Trigger()
// Returns IEvent<EventArgs> value (instead of second element of the tuple)
evt.Publish
This represents event using IEvent<_> value (and doesn't generate .NET compatible event if you expose it as a property) and it uses generic Handler<_> delegate from F# libraries.
(If you want to generate .NET compatible event usable from C# then you need to add CLIEvent attribute and you can use variant of Event that takes delegate as generic parameter as described in the answer already mentioned by others)
EDIT: I posted a more complete F# snippet (with nicer formatting) here: http://fssnip.net/1d
Is there a clever way to record changes made to an object in F#?
I have been researching F# as a way to build an object model that replicates itself over the network. One task I need to solve is how to detect changes made to objects so I can send only changes to clients
Note: I am looking for answers other than "implement INotifyPropertyChanged" or "do something that can easily be done in C#". If that is the only way to solve the problem in F# then F# is not the tool im looking for.
Why F#? Because I am not satisfied with the ways this state observer pattern is implemented in C#. Hence I am investigating if there is some elegant way to implement it in a dynamic language, starting with F#.
Instead of detecting and notifying changes as they happen, you could make your classes immutable (for example by using the standard immutable types like records and unions, or by making the object contain only immutable things). Then you could write a function that "diffs" two instances of a class, and have some agent that looks for changes on a schedule or based on some trigger and sends the diffs to the other end.
Because the data would be immutable, the agent would only need to retain a pointer to the version it last sent. The diffing function itself could either be written by hand for each class, which would allow for an efficient implementation that takes the properties of the data into account, or you could write a generic one using reflection.
An example of INotifyPropertyChanged use in F#.
type DemoCustomer() =
let mutable someValue = 0
let propertyChanged = Event<_, _>()
member this.MyProperty
with get() = someValue
and set(x) =
someValue <- x
propertyChanged.Trigger(this, PropertyChangedEventArgs("MyProperty"))
interface INotifyPropertyChanged with
[<CLIEvent>]
member this.PropertyChanged = propertyChanged.Publish
How about using the INotifyPropertyChanged interface? and raise events that cause the data to be replicated when it is changed?
I'd use a proxy library: Castle DynamicProxy, LinFu, Spring.NET, etc.
Using a proxy library you can easily implement INotifyPropertyChanged in a transparent, non-invasive way.
Can you use reflection to walk the object fields and see what changed? If they contain immutable F# data then equality checks will pick up the changes. You can then send the diffs relative to the last sent object.