Isolate the sharing of the state of an object? - f#

My code uses the following shared library
Module Shared
let state = new AClrClass()
let fun1 x .... = // shared function
.... // uses state
Examples of using the shared library, the state is shared by all the functions even when multiple main functions (in the following code) are called in parallel.
Module Caller
let f1 x = Shared.fun1 x .... // other code omitted
let f2 x = Shared.fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
Now I will need to switch to a different implementation of Shared which defines a class (so each calling of Caller.main will have its own state)
Module Shared
type Shared () =
let state = new AClrClass()
member __.Fun1 x .... = // shared function
.... // uses state
I will need to update the Caller module. There may be the following approaches
Add another parameter of aClrObj to all the functions call the Shared library
Module Caller
let f1 o x .... = o.Fun1 x .... // other code omitted
let f2 o x .... = o.Fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
let aClrObj = new AClrClass()
f1 aClrOjb x ....
Define a mutable variable and set it in the main function.
Module Caller
let mutable o = new AClrClass()
let f1 x .... = o.Fun1 x .... // other code omitted
let f2 x .... = o.Fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
o <- new AClrClass()
let aClrObj = new AClrClass()
f1 aClrOjb x ....
Which approach is more F# idiomatic? How should the code be architectured?

Expanding from my comment
It's not quite clear from your code samples exactly what your module is supposed to do. However, in general, you can pipe state through functions by having each function take the state as its last parameter, and return the new state as its value. Then, your main function (or whatever function is publicly exposed) can initialize the state and pipe it through whatever functions it calls to perform the work, returning the final state.
Here's a simple example:
type State = State of int
let add x (State state) =
State (state + x)
let subtract x (State state) =
State (state - x)
let multiply x (State state) =
State (state * x)
let divide x (State state) =
State (state / x)
let main () =
State 0
|> add 3
|> multiply 4
|> subtract 2
|> divide 5
// returns (State 2)
This uses a State object to thread the current state of execution through each function. Each function takes the current state and performs its operation on it, returning the new state. The main function uses the other functions to perform a specific, more complex operation, threading the current state through each function by using the pipe-forward operator.

Related

How to set a timercalling a member method in F#?

I am trying to achieve this:
type Test() =
member val MyTimer : Timer = new Timer(TimerCallback TimerEvent)
member mutable Status : bool = false
...
member this.StartTimer =
this.MyTimer....
member this.TimerEvent =
if this.Status...
I need to create a timer that is part of the class instance, needs to be referenced by several methods (to start / stop it) but also, the timer ballback needs to be able to access some of the inner states.
I can't find the syntax to create the timer object so that it has access to class members and class members have access to it.
But I think I'm having some confusion:
It looks like I can do the timer like this:
member this.Timer : Timer = new Timer(TimerCallback (fun x -> printfn "%A" x))
but I though member was reserved for methods and val for the fields? can anyone clarify this? I can do member this.xxx, but I can't do val this.xxx..
I found this post because I need to implement a scheduled job in F# for the first time.
I'm also learning F# and it is the first time I saw "val", so I read something about it.
Regarding your question.
"member val ... " is a particular case described here:
The val Kweyword
Another use of the val keyword is in conjunction with the member keyword to declare an auto-implemented property.
I think this answer your question.
Said that, I looked up to your code:
member this.Timer : Timer = new Timer(TimerCallback (fun x -> printfn "%A" x))
This is not correct to me because it exposes the Timer publicly.
I like the idea to have an object (the Timer) declared but not initialized, so that I can refer to its instance within multiple methods (Start/Stop) and (most important) Dispose it properly.
So, also regarding your doubt about the syntax...
I can't find the syntax to create the timer object so that it has access to class members and class members have access to it.
I came out with the following example:
open System
open System.Threading
type public ExampleJob () as me =
let timer_elapsed:TimerCallback = TimerCallback(fun (state) -> me.OnCall(state) )
[<DefaultValue>] val mutable private timer:Timer // no need to initialize
member __.IsActive with get() = __.timer <> null
member __.Start(frequency:TimeSpan) =
__.Stop() // Dispose previous timer if exists
__.timer <- new Timer(timer_elapsed)
__.timer.Change(0, int(frequency.TotalMilliseconds)) |> ignore
member __.Stop() =
if __.timer <> null then __.timer.Dispose() ; __.timer <- null
member private __.OnCall (state:obj) =
// do the real work here
// The state object is the Timer object.
Console.WriteLine(sprintf"OnCall(%i) at %s" ((state :?> Timer).GetHashCode()) (DateTime.Now.ToString("ss:fff")))
interface IDisposable with
member this.Dispose(): unit =
this.Stop()
Checking the Timer itself is enough to expose the Status (IsActive/IsRunning).
Start/Stop can be called in any sequence an number of times. A new call to Start() will reset the current timer to the new desired frequency.
It is not thread safe and I haven't tested it enough, so I'm not 100% sure the timer "survives" when/if the whole class is no more referenced.
Anyway I hope this is a useful example.
[Update]
new version with the suggestion of Ben
open System
type ExampleJob () =
let timer = new Timers.Timer()
let OnCall = fun(args) ->
// do real job here
Console.WriteLine(sprintf"OnCall(%O) at %s" args (DateTime.Now.ToString("ss:fff")))
do timer.Elapsed.Add(OnCall) // carefull to add it only once
member this.IsActive with get() = timer.Enabled
member this.Start(frequency:TimeSpan) =
timer.Interval <- frequency.TotalMilliseconds
timer.AutoReset <- true
timer.Enabled <- true
OnCall() // first call (if needed)
timer.Start()
member this.Stop() = timer.Enabled <- false
interface IDisposable with
member this.Dispose(): unit =
timer.Dispose()

Random / State workflow in F#

I'm trying to wrap my head around mon-, err, workflows in F# and while I think that I have a pretty solid understanding of the basic "Maybe" workflow, trying to implement a state workflow to generate random numbers has really got me stumped.
My non-completed attempt can be seen here:
let randomInt state =
let random = System.Random(state)
// Generate random number and a new state as well
random.Next(0,1000), random.Next()
type RandomWF (initState) =
member this.Bind(rnd,rest) =
let value, newState = rnd initState
// How to feed "newState" into "rest"??
value |> rest
member this.Return a = a // Should I maybe feed "initState" into the computation here?
RandomWF(0) {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c]
} |> printfn "%A"
Edit: Actually got it to work! Not exactly sure how it works though, so if anyone wants to lay it out in a good answer, it's still up for grabs. Here's my working code:
type RandomWF (initState) =
member this.Bind(rnd,rest) =
fun state ->
let value, nextState = rnd state
rest value nextState
member this.Return a = fun _ -> a
member this.Run x = x initState
There are two things that make it harder to see what your workflow is doing:
You're using a function type for the type of your monad,
Your workflow not only builds up the computation, it also runs it.
I think it's clearer to follow once you see how it would look without those two impediments. Here's the workflow defined using a DU wrapper type:
type Random<'a> =
Comp of (int -> 'a * int)
let run init (Comp f) = f init
type Random<'a> with
member this.Run(state) = fst <| run state this
type RandomBuilder() =
member this.Bind(Comp m, f: 'a -> Random<_>) =
Comp <| fun state ->
let value, nextState = m state
let comp = f value
run nextState comp
member this.Return(a) = Comp (fun s -> a, s)
let random = RandomBuilder()
And here is how you use it:
let randomInt =
Comp <| fun state ->
let rnd = System.Random(state)
rnd.Next(0,1000), rnd.Next()
let rand =
random {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c ]
}
rand.Run(0)
|> printfn "%A"
In this version you separately build up the computation (and store it inside the Random type), and then you run it passing in the initial state. Look at how types on the builder methods are inferred and compare them to what MSDN documentation describes.
Edit: Constructing a builder object once and using the binding as an alias of sorts is mostly convention, but it's well justified in that it makes sense for the builders to be stateless. I can see why having parameterized builders seems like a useful feature, but I can't honestly imagine a convincing use case for it.
The key selling point of monads is the separation of definition and execution of a computation.
In your case - what you want to be able to do is to take a representation of your computation and be able to run it with some state - perhaps 0, perhaps 42. You don't need to know the initial state to define a computation that will use it. By passing in the state to the builder, you end up blurring the line between definition and execution, and this simply makes the workflow less useful.
Compare that with async workflow - when you write an async block, you don't make the code run asynchronously. You only create an Async<'a> object representing a computation that will produce an object of 'a when you run it - but how you do it, is up to you. The builder doesn't need to know.

Change async workflow builder to count steps?

My understanding is that what a workflow builder does is that it first "builds" the expression, and then subsequently executes it. So given that it first builds the expression, it should be able to count the number of let! statements before actually executing, right? And then it should be able to inject some logging that monitors progress? So is it possible to rework the async builder to automatically report progress and kill the printfn redundancy below?
async {
let! a = doSomething1 ()
printfn "%d/%d" 1 4
let! b = doSomething2 a
printfn "%d/%d" 2 4
let! c = doSomething3 b
printfn "%d/%d" 3 4
let! d = doSomething4 c
printfn "%d/%d" 4 4
return d
}
For loops, I guess just assume that the whole loop is a single step. Only top-level expressions count as steps here.
(Note if there's a way to do this without making a whole new workflow builder I guess that's fine too).
Note I've already gone through the path of a) making a "Task" iterator that just iterates tasks (but then you lose e.g. use handling, so it ended up being inadequate), and b) making a task counter, but that always had to be seeded and iterated manually so I'm hoping for something better.
As you tagged the question with the tag monads, I'll start by a theoretical nitpick. What you want to do would not actually be a monad. The problem is that monads require certain laws (see the Haskell page on monads). For F#, this means that the following two snippets should mean the same thing:
let computation1 =
async { let! x = m
return x }
let computation2 = m
This would not be the case for the extension you suggest, because computation1 has one more let! than computation2. Now, I do not think this is actually a problem - the logging could still be useful (even if it may give different results than you'd expect in some cases).
Adding this feature to F# async is not as easy - the problem is that you'd need to define your own type that replaces (or wraps) standard Async<'T>. The type needs to store the number of steps. If you can store the number of steps somewhere else (e.g. some mutable counter), then you just need to redefine the computation builder for async.
Here is a minimal example that does something like this - it just prints "step" for each let!:
// A custom computation builder that redirects all operations to
// the standard 'async' builder, but prints "step" in the Bind method
type LogAsyncBuilder() =
member x.Bind(c1, f) = async {
let! arg = c1
printfn "step!"
return! f arg }
member x.Return(v) = async.Return(v)
member x.ReturnFrom(c) = async.ReturnFrom(c)
// An instance of our custom computation builder
let logAsync = LogAsyncBuilder()
// Example that prints 'step' 4 times (for every Bind - let!)
let doSomething n = logAsync {
return n + 10 }
logAsync {
let! a = doSomething 0
let! b = doSomething a
let! c = doSomething b
let! d = doSomething c
return d }
|> Async.RunSynchronously
You could use a tuple ('a, int, int) to track the current result, the total number of steps and the number executed so far. Then you could write a function to take the current state, and the next async function to execute e.g.
//create the initial state
let startCount steps = ((), 0, steps)
let withCount af (a, c, steps) = async {
let nc = c + 1
let! res = af a
do printfn "%d %d" nc steps
return (res, nc, steps)
}
withCount takes a function which returns the next async operation, and the current state. It creates the next workflow, increments the number of executed steps and prints the status before returning the new state.
You can then use it like:
async {
let init = startCount 4
let! t = withCount doSomething init
let! t2 = withCount doSomething2 t
let! (r, _, _) = withCount doSomething3 t2
return r
}

Wrapping a recursive function to count the number of function calls

Say I have a recursive function that I want to know how many times the function has called itself per input value. Rather than putting printf expressions or changing the return type to include the number of calls, is it possible to "wrap" the function with another to achive this? I would like the wrapped function to return the number of function calls and the original functions result. It should be reusable across different functions.
Here is what I have and it doesn't work.
open System
open System.IO
open System.Collections.Generic
/// example recursive function
let rec getfilenames dir =
seq {
yield Directory.GetFiles dir
for x in Directory.GetDirectories dir do yield! getfilenames x}
/// function to count the number of calls a recursive function makes to itself
let wrapped (f: 'a -> 'b) =
let d = new Dictionary<'a, int>()
fun x ->
let ok, res = d.TryGetValue(x)
if ok then d.[x] <- d.[x] + 1
else
d.Add(x, 1)
d, f x
> let f = wrapped getfilenames
let calls, res = f "c:\\temp";;
val f : (string -> Dictionary<string,int> * seq<string []>)
val res : seq<string []>
val calls : Dictionary<string,int> = dict [("c:\temp", 1)]
This is not going to work, because getfilenames is defined as calling getfilenames, not any other function and especially not a function defined after that. So, as soon as your wrapper calls the function, the function will ignore your wrapper and start calling itself.
What you need to do is move the recursion out of the getfilenames function and into another function, by providing the function to be called recursively as a parameter.
let body recfun dir =
seq {
yield Directory.GetFiles dir
for x in Directory.GetDirectories dir do yield! recfun x}
let rec getfilenames dir = body getfilenames dir
Now, you can wrap body before plugging it into a recursive function:
let wrap f =
let d = (* ... *) in
d, fun recfun x ->
let ok, res = d.TryGetValue(x)
if ok then d.[x] <- d.[x] + 1
else d.Add(x, 1)
f recfun x
let calls, counted_body = wrap body
let getfilenames dir = counted_body getfilenames dir
Note that the wrap function returns both the wrapped function (with a signature identical to the original function) and the dictionary, for external access. The number of calls will then be found in calls.
As Victor points out, you cannot take a recursive function and "inject" some behavior into the place where the recursive call happens (because the function is already complete). You'll need to provide some extension point for that. In Victor's solution, this is done by taking a function to be called recursively as an argument, which is the most general solution.
A simpler option is to use F# value recursion which allows you to create a function value and use it in its declaration. You can use this to create a recursive function by calling another function that adds some behavior to the function (e.g. counting):
let rec factorial = counted (fun x ->
if x = 0 then 1
else x * (factorial (x - 1)) )
factorial 10
Inside the lambda function, we can directly access the function we're defining, so there is no need for passing function to be called recursively as additional parameter. The function counted simply wraps the given function f and adds some functionality:
let counted f =
let count = ref 0
(fun x ->
count := !count + 1;
printfn "call: %d" (!count)
f x)
Thanks to the value recursion, the functionality will be added to the factorial function (and so when it calls itself, it will call the version with added counting support).

Is it possible to use the pipeline operator to call a method on a returned object?

Is it possible to call a method on a returned object using the pipeline infix operator?
Example, I have a .Net class (Class1) with a method (Method1). I can currently code it like this:
let myclass = new Class1()
let val = myclass.Method1()
I know I could also code it as such
let val = new Class1().Method1()
However I would like to do be able to pipeline it (I am using the ? below where I don't know what to do):
new Class1()
|> ?.Method1()
Furthermore, say I had a method which returns an object, and I want to only reference it if that method didn't return null (otherwise bail?)
new Class1()
|> ?.Method1()
|> ?? ?.Method2()
Or to make it clearer, here is some C# code:
public void foo()
{
var myclass = new Class1();
Class2 class2 = myclass.Method1();
if (class2 == null)
{
return;
}
class2.Method2();
}
You can define something similar to your (??) operator fairly easily (but operators can't start with a question mark):
let (~??) f x =
if (x <> null) then
f x
Unfortunately, your pipelined code will need to be a bit more verbose (also, note that you can drop the new keyword for calling constructors):
Class1()
|> fun x -> x.Method1()
Putting it all together:
Class1()
|> fun x -> x.Method1()
|> ~?? (fun x -> x.Method2())
Using a custom operator as 'kvb' suggests is definitely an option. Another approach that you may find interesting in this case is to define your own 'computation expression' that automatically performs the check for null value at every point you specify. The code that uses it would look like this:
open System.Windows.Forms
// this function returns (0) null, or (1) btn whose parent is
// null or (2) button whose parent is not null
let test = function
| 1 -> new Button(Text = "Button")
| 2 -> new Button(Text = "Button", Parent = new Button(Text = "Parent"))
| _ -> null
let res =
safe { let! btn = test(2) // specify number here for testing
// if btn = null, this part of the computation will not execute
// and the computation expression immediately returns null
printfn "Text = %s" btn.Text
let! parent = btn.Parent // safe access to parent
printfn "Parent = %s" parent.Text // will never be null!
return parent }
As you can see, when you want to use a value that can potentially be 'null', you use let! inside the computation expression. The computation expression can be defined so that it immediately returns null if the value is null and runs the rest of the computation otherwise. Here is the code:
type SafeNullBuilder() =
member x.Return(v) = v
member x.Bind(v, f) =
if v = null then null else f(v)
let safe = new SafeNullBuilder()
BTW: If you want to learn more about this, it is very similar to 'Maybe' monad in Haskell (or computation working with F# option type).

Resources