memoization eine reine Funktion (nicht nur vom Typ unit -> 'a
, aber andere auch) als Suchschlüssel unmöglich, weil Funktionen im Allgemeinen keinen Gleichheitsvergleich für die reason haben.
Es könnte scheinen, dass für diese spezifische Art von Funktion unit -> 'a
es möglich wäre, mit einem benutzerdefinierten Gleichheitsvergleich zu kommen. Der einzige Ansatz zum Implementieren eines solchen Vergleichs über Extreme hinaus (Reflektion, IL, etc.) wäre , wobei die Lookup-Funktion als f1 = f2 iff f1() = f2()
aufgerufen wird, was offensichtlich jegliche Leistungsverbesserung, die von Memoisierung erwartet wird, aufhebt.
So, vielleicht, wie bereits erwähnt, sollten für diesen Fall Optimierungen um lazy
Muster aufgebaut werden, aber nicht memoization
eins.
UPDATE: In der Tat, nach dem zweiten Blick auf die Frage alle oben über Funktionen fehlenden Gleichheitsvergleich ist richtig, aber nicht anwendbar, weil memoization innerhalb jeder einzelnen cache
der Funktion von der Schließung geschieht. Auf der anderen Seite ist für diese spezielle Art von Funktionen mit der Signatur unit->'a
, d. H. Höchstens ein einzelner Wert des Arguments, die Verwendung von Dictionary
mit dem meisten Eintrag ein Overkill. Die folgende ähnlich Stateful, aber einfachere Implementierung mit nur einem Wert memoized tun:
let memoize2 f =
let notFilled = ref true
let cache = ref Unchecked.defaultof<'a>
fun() ->
if !notFilled then
cache := f()
notFilled := false
!cache
verwendet als let foo = memoize2(fun() -> ...heavy on time and/or space calculation...)
mit dem ersten Gebrauch foo()
Durchführung und das Ergebnis der Berechnung zu speichern und alle aufeinanderfolgenden foo()
nur den gespeicherten Wert wiederzuverwenden.
Memoize wird im Allgemeinen verwendet, um Berechnungen für ein Argument zwischenzuspeichern, bei dem das Argument als Suchschlüssel verwendet wird. 'Lazy' ist in diesem Fall das richtige Werkzeug. – Daniel
Sie _could_ wrap 'faul', etwa so:' memoize f = let result = lazy (f()) in fun() -> result.Value' – Daniel