Ramesh Kadambi
Ramesh Kadambi

Reputation: 536

F# Error compiling

I have the following F# Code that is causing a compile error:

persistence.fs(32,21): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

The error is at the line "serializer.write...."

Any help would be appreciated.

namespace persisitence
open System.Collections.Generic
open System
open System.IO

type LocalData<'T> =
    struct
        val mutable elements_ : 'T list
        val mutable lock_ : obj
        new(e: 'T list) = { elements_ = e ; lock_ = new obj() }
    end

type BinaryPersistenceOut<'T, ^W when ^W: (member write : ('T * BinaryWriter) -> unit)>(fn: string, serializer: ^W) as this = 
    let writer_ = new BinaryWriter(File.Open(fn, FileMode.Append))
    let mutable localdata_ = new LocalData<'T>([])
    let serializer_ = serializer
    let NUM_SECS_IN_MIN = 60
    let NUM_MSECS_IN_SEC = 1000
    let NUM_MIN_BETWEEN_COMMITS = 2
    let TIME_TO_WAIT = 15
    let closed_ = false

    let freq_ = NUM_MIN_BETWEEN_COMMITS * NUM_SECS_IN_MIN * NUM_MSECS_IN_SEC
    let path_ = fn
    let timer_ = new System.Timers.Timer((float) (NUM_MIN_BETWEEN_COMMITS * NUM_MSECS_IN_SEC) )

    let writetofile = 
        fun (arg: Timers.ElapsedEventArgs ) ->
            lock localdata_.lock_ ( fun () -> 
             if closed_ = false then
                for elem in localdata_.elements_ do
                    serializer.write(elem, writer_)
             )  

    do 
        timer_.Elapsed.Add(writetofile)

Upvotes: 1

Views: 154

Answers (1)

Mark Seemann
Mark Seemann

Reputation: 233427

Although it'd be nice if you could invoke the write function like serializer.write(elem, writer_), you can't. You have to invoke it like this instead:

(^W: (member write : ('T * BinaryWriter) -> unit) (serializer, (elem, writer_)))

Full code block:

type BinaryPersistenceOut<'T, ^W when ^W: (member write : ('T * BinaryWriter) -> unit)> (fn: string, serializer: ^W) as this = 
    let writer_ = new BinaryWriter(File.Open(fn, FileMode.Append))
    let mutable localdata_ = new LocalData<'T>([])
    let serializer_ = serializer
    let NUM_SECS_IN_MIN = 60
    let NUM_MSECS_IN_SEC = 1000
    let NUM_MIN_BETWEEN_COMMITS = 2
    let TIME_TO_WAIT = 15
    let closed_ = false

    let freq_ = NUM_MIN_BETWEEN_COMMITS * NUM_SECS_IN_MIN * NUM_MSECS_IN_SEC
    let path_ = fn
    let timer_ = new System.Timers.Timer((float) (NUM_MIN_BETWEEN_COMMITS * NUM_MSECS_IN_SEC) )

    let writetofile = 
        fun (arg: Timers.ElapsedEventArgs ) ->
            lock localdata_.lock_ ( fun () -> 
             if closed_ = false then
                for elem in localdata_.elements_ do
                    (^W: (member write : ('T * BinaryWriter) -> unit) (serializer, (elem, writer_)))
             )  

    do 
        timer_.Elapsed.Add(writetofile)

Caveat: this compiles, but I have no idea if it does what you want it to do.

Upvotes: 2

Related Questions