F# - Class member does not keep state - f#

I wrote a wrapper around List. I expect the internal list to keep state but it doesn't. What am I doing wrong? The methods are definitely executed but the internal list is always empty.
open System
open System.Collections.Generic
open NUnit.Framework
type MyList() =
member this.List = List<char>()
member this.AddX =
printfn "AddX called"
this.List.Add('X')
member this.CountX: int =
printfn "CountX called"
this.List.Count
[<Test>]
let TestX () =
let mylist = MyList()
mylist.AddX
mylist.AddX
Assert.AreEqual(2, mylist.CountX)
Tried putting a mutable keyword in different places (no success)

The problem is that every time you call the List member of MyList, it creates a new list, so the class isn't keeping internal state the way you want. (You can verify this by adding a printfn statement to the List method.)
To fix this problem, change the List member to be a value, which is initialized only once per class instance:
type MyList() =
member val List = List<char>()
...
Alternatively, you can use a let-bound value instead:
type MyList() =
let list = List<char>()
member this.AddX = list.Add('X')
member this.CountX = list.Count

Related

F# ASP.net MVC Project won't compile in VS 2019

I've been revisiting one of my old experiments. The code below is a file I added to Daniel Mohl's F# MVC5 project which I created in Visual Studio 2015. It compiled and worked in VS2015 (and still does) but when I try to compile it in VS2019 I get an error message on the |> this.View lines towards the end: "FS0405: A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope". Does anyone have any idea what I need to do to get rid of the error
namespace fsmvcproject.Models
open System
open System.ComponentModel.DataAnnotations
type Newarticle() =
[<Key>]member val Id = 0 with get, set
member val Headline = "" with get, set
member val Author = "" with get, set
member val Publication = "" with get, set
member val Intro = "" with get, set
member val Story = "" with get, set
namespace fsmvcproject.Repositories
open System.Data.Entity
open fsmvcproject.Models
open System.Collections.Generic
type SGdbEntities() =
inherit DbContext("Data Source=127.0.0.1\SQLEXPRESS;Persist Security Info=True;Initial Catalog=SG;User ID=xxxx;Password=xxxx")
[<DefaultValue()>] val mutable newarticles : IDbSet<Newarticle>
member x.Newarticles with get() = x.newarticles and set v = x.newarticles <- v
type NewarticlesRepository() =
member x.GetAll () =
use context = new SGdbEntities()
query { for a in context.Newarticles do
sortByDescending a.Id
select a }
|> Seq.toList
member x.GetDetail (id) =
use context = new SGdbEntities()
query { for a in context.Newarticles do
where (a.Id = id)
select a }
|> Seq.toList
namespace fsmvcproject.Controllers
open fsmvcproject.Repositories
open System.Web.Mvc
[<HandleError>]
type ArticlesController(repository :NewarticlesRepository) =
inherit Controller()
new() = new ArticlesController(NewarticlesRepository())
member this.Index () =
repository.GetAll()
|> this.View
member this.Detail (id) =
repository.GetDetail(id)
|> this.View
I think the problem here is that View is a protected method, which means that you can call it directly from your derived class, but you can't treat it like a first-class F# function.
Thus, to fix the compiler error, try changing model |> this.View to this.View(model).

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()

F# sequence with at least one element

Beginner in F# here
I want to create a type, which is a sequence of another concrete type (Event) with at least one element. Any other elements can be added anytime later. Normally in C# I would create a class with a private List<Event> and public methods.
But I want to do it with a functional approach and not imitate the C# approach. Or at least try.
My train of thought:
Let's create a type "of seq" and give it a constructor requiring instance of the Event type
type Event = Event of string
type PublishedEvents = EventList of seq<Event> with
static member create (event:Event) = EventList(Seq.singleton event)
Now let's add an "add" method for adding another optional Event instances
type PublishedEvents with
member this.add(event:Event) = Seq.append this [event]
But that doesn't work, F# complains that "this" is not compatible with seq<'a>.
So I tried this:
type PublishedEvents with
member this.add (event:Event) : PublishedEvents = EventList(Seq.append this [event])
Now it complains that "this" is not compatible with seq<Event>...which is confusing me now since few lines above it says EventList of seq<Event> ... so I guess I need to somehow convert EventList back to seq<Event> so I can then use Seq.append ?
let convertFunction (eventList:PublishedEvents) : seq<Event> = ???
But I have no idea how to do this.
Am I even going the right direction? Is it better for this to mimic a C# class with a backing field? Or am I missing something?
The actual sequence of events is wrapped inside an EventList discriminated union case.
You can unwrap it and re-wrap it like this:
type PublishedEvents with
member this.add(event:Event) =
match this with
| EventList events -> Seq.append events [event] |> EventList
However, I have to question the value of creating this PublishedEvents type in the first place, if it's just a single EventList case containing a sequence that requires you to wrap and unwrap values repeatedly.
Also, please be aware that this add method doesn't change the existing PublishedEvents. It creates a new one with a new sequence of events, because of the way that Seq.append works, because seq<'a> is actually just F#'s name for System.Collections.Generic.IEnumerable<'a>).
Furthermore, your approach does not prevent creation of a non-empty event sequence. EventList is a public constructor for PublishedEvents so you can just write:
EventList []
A simple way to make the type system enforce a non-empty sequence is this:
type NonEmptySeq<'a> = { Head : 'a; Tail : seq<'a> } with
static member Create (x:'a) = { Head = x; Tail = [] }
member this.Add x = { this with Tail = Seq.append this.Tail [x] }
let a = NonEmptySeq.Create (Event "A")
let b = a.Add (Event "B")
But again, these sequences are immutable. You could do something similar with a C# List<'a> if you need mutation. In F# it's called a ResizeArray<'a>:
type NonEmptyResizeArray<'a> = { Head : 'a; Tail : ResizeArray<'a> } with
static member Create (x:'a) = { Head = x; Tail = ResizeArray [] }
member this.Add x = this.Tail.Add x
let a = NonEmptyResizeArray.Create (Event "A")
a.Add (Event "B")
I propose that you go even more functional and not create members for your types - have it done in your functions. For example this would achieve the same and I would argue it's more idiomatic F#:
type Event = Event of string
type PublishedEvents = EventList of Event * Event list
let create e = EventList (e,[])
let add (EventList(head,tail)) e = EventList(e,head::tail)
let convert (EventList(head,tail)) = head::tail |> Seq.ofList
let myNewList = create (Event "e1")
let myUpdatedList = add myNewList (Event "e2")
let sequence = convert myUpdatedList
val sequence : seq = [Event "e2"; Event "e1"]
On the other hand if your aim is to interop with C# your approach would be easier to consume on C# side.

Style guidelines for global variables in F#

For a project I am working on I need a global variable(technically I don't, I could build it and then pass it to every single function call, and let every single function call know about it, but that seems just as hacky, less readable and more work.)
The global variables are look up tables(endgame, opening book and transpositions/cache) for a game.
The fact that some of the code may lose some of it's indempotent behavior is actually the point(speedups) in short, yes I know global mutable state is bad, it's really worth it in this case(10x+ performance improvement)
So here's the question, "build a singleton or use a static value in a static class with combinators"
They are effectively identical but I am curious what people have done before on this sort of problem
Or alternatively, should I be passing the thing around to everyone(or at least a reference to it anyways),is that really the best answer?
Here is a solution similar to the one posted by #Yin Zhu's, but using abstract types to specify a usage interface for the mutable value, a local definition to encapsulate it and object literals to provide an implementation (this is taken from Expert F#--which is co-authored by Don Syme):
type IPeekPoke =
abstract member Peek: unit -> int
abstract member Poke: int -> unit
let makeCounter initialState =
let state = ref initialState
{ new IPeekPoke with
member x.Poke(n) = state := !state + n
member x.Peek() = !state }
You can also do it with static fields, like this:
type Common() =
static let mutable queue : CloudQueue = null
static let mutable storageAccount : CloudStorageAccount = null
static member Queue
with get() = queue
and set v = queue <- v
static member StorageAccount
with get() = storageAccount
and set v = storageAccount <- v
In another module, just:
open Common
Common.Queue <- xxxx
here is the convention used in F# PowerPack Matrix library (\src\FSharp.PowerPackmath\associations.fs):
// put global variable in a special module
module GlobalAssociations =
// global variable ht
let ht =
let ht = new System.Collections.Generic.Dictionary<Type,obj>()
let optab =
[ typeof<float>, (Some(FloatNumerics :> INumeric<float>) :> obj);
typeof<int32>, (Some(Int32Numerics :> INumeric<int32>) :> obj);
...
typeof<bignum>, (Some(BigRationalNumerics :> INumeric<bignum>) :> obj); ]
List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
ht
// method to update ht
let Put (ty: System.Type, d : obj) =
// lock it before changing
lock ht (fun () ->
if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
ht.Add(ty, d))

Static Member Indexed Properties

Is it possible to create static member indexed properties in F#? MSDN show them only for instance members, however, I'm able to define the following class:
type ObjWithStaticProperty =
static member StaticProperty
with get () = 3
and set (value:int) = ()
static member StaticPropertyIndexed1
with get (x:int) = 3
and set (x:int) (value:int) = ()
static member StaticPropertyIndexed2
with get (x:int,y:int) = 3
and set (x:int,y:int) (value:int) = ()
//Type signature given by FSI:
type ObjWithStaticProperty =
class
static member StaticProperty : int
static member StaticPropertyIndexed1 : x:int -> int with get
static member StaticPropertyIndexed2 : x:int * y:int -> int with get
static member StaticProperty : int with set
static member StaticPropertyIndexed1 : x:int -> int with set
static member StaticPropertyIndexed2 : x:int * y:int -> int with set
end
But when I try to use one, I get an error:
> ObjWithStaticProperty.StaticPropertyIndexed2.[1,2] <- 3;;
ObjWithStaticProperty.StaticPropertyIndexed2.[1,2] <- 3;;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error FS1187: An indexer property must be given at least one argument
I tried a few different syntax variations and none worked. Also weird is that when I hover over set in VS2010 for one of the definitions in the type, I get info about ExtraTopLevelOperators.set.
If you wanted to recover the Type.Prop.[args] notation, then you can define a simple object to represent an indexable property with the Item property:
type IndexedProperty<'I, 'T>(getter, setter) =
member x.Item
with get (a:'I) : 'T = getter a
and set (a:'I) (v:'T) : unit = setter a v
type ObjWithStaticProperty =
static member StaticPropertyIndexed1 =
IndexedProperty((fun x -> 3), (fun x v -> ()))
ObjWithStaticProperty.StaticPropertyIndexed1.[0]
This returns a new instance of IndexedProperty every time, so it may be better to cache it. Anyway, I think this is quite nice trick and you can encapsulate some additional behavior into the property type.
A digression: I think that an elegant extension to F# would be to have first-class properties just like it has first-class events. (You could for example create properties that automatically support INotifyPropertyChange with just one line of code)
I believe that you call indexed properties using a different syntax (whether instance or static):
ObjWithStaticProperty.StaticPropertyIndexed2(1,2) <- 3
The only semi-exception to this is that an Item property on an instance x can be called via x.[...] (that is, Item is omitted and brackets are used around the arguments).

Resources