I am struggling to get memoization to work when the memoized function is an abstract function which is overridden/defined within a subclass rather than the parent class.
When the memoized function is defined in the parent class, it works fine. When I define the signature of the memoized function in the parent class, and then override it in the subclass, I can't figure out the appropriate syntax.
open System
let Memoize f =
let dict = Dictionary<_, _>()
fun c ->
let exists, value = dict.TryGetValue c
match exists with
| true -> value
| _ ->
let value = f c
dict.Add(c, value)
value
[<AbstractClass>]
type ParentClass() as this =
let someparam = DateTime(2022,1,1)
let SlowNumber100InParentClass(t) =
System.Threading.Thread.Sleep(1000)
100.0
member val MemoParentClassSlow100 = Memoize SlowNumber100InParentClass
member this.MultiplyBy2A = (this.MemoParentClassSlow100 someparam) * 2.0
abstract MemoSubClassSlow100: DateTime->float
member this.MultiplyBy2B = (this.MemoSubClassSlow100 someparam) * 2.0
type MyClass() as this =
inherit ParentClass()
let SlowNumber100InSubClass(t) =
System.Threading.Thread.Sleep(1000)
100.0
override this.MemoSubClassSlow100(t) = Memoize SlowNumber100InSubClass t // doesn't "memoize"
//override val MemoSubClassSlow100 = Memoize SlowNumber100InSubClass // This feels intuitive to me, but error is "No abstract property was found that corresponds to this override"
// ??? somehow else ???
[<EntryPoint>]
let main args =
let x = new MyClass()
for i in 1..10 do
Console.WriteLine(x.MultiplyBy2A) // this is fast
for i in 1..10 do
Console.WriteLine(x.MultiplyBy2B) // this is slow
0
You're very close. Just use member val
in the subclass to hold the memoized function, since that member doesn't override anything in the parent class:
type MyClass() =
inherit ParentClass()
let SlowNumber100InSubClass(t) =
System.Threading.Thread.Sleep(1000)
100.0
member val MemoSubClassSlow100_ = Memoize SlowNumber100InSubClass
override this.MemoSubClassSlow100(t) = this.MemoSubClassSlow100_ t
Personally, I think let
is usually preferable to member val
, though:
let memoSubClassSlow100 = Memoize SlowNumber100InSubClass
override _.MemoSubClassSlow100(t) = memoSubClassSlow100 t