F# Memoization - Persist? - functional-programming

What's the best way to persist/save the results of memoization so it can be loaded later?
There's this standard code snippet in F# for implementing memoization:
let memoize f =
let dict = Dictionary<_, _>();
fun c ->
let exist, value = dict.TryGetValue c
match exist with
| true -> value
| _ ->
let value = f c
dict.Add(c, value)
value
let mySlowFunc x=
// something very slow
0
let myFastFunc = memoize mySlowFunc
After calling myFastFunc many times, I will have a dictionary full of results for mySlowFunc for various x's. I want to persist these results so ideally I can do something like:
let saveMemoziationResults myFastFunc "results.file" = ... // saves the dict to a file
let loadMemoziationResults "results.file" // loads the dict from a file
I can't figure out a way to "access" that dict in order to save it.

You could move dict creation to the caller, like
let memoizeBase dict =
let memoize f = …
memoize
And using it like
let dict = new…
let memoize = memoizeBase dict
// use memoize and save/load dict when needed

Related

F# Memoization Within a Class

I am struggling to make Memoization work in F# when the function I want to Memoize is a member of a class.
The Dictionary appears to be cleared every time - and so nothing is actually memoized, the result is always recomputed. The same code but with the key functions outside of a calls of a class works just fine.
open System
module TestMemo
open System
open System.IO
open System.Collections.Generic
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
type MyClass() as this =
let rec AddToOne(x) = if x <= 1 then 1 else x + AddToOne(x-1)
let rec AddToOneSkip(x) = if x <= 1 then 1 else x + AddToOneSkip(x-2)
member this.MemoAddToOne = Memoize AddToOne
member this.MemoAddToOneSkip = Memoize AddToOneSkip
[<EntryPoint>]
let main args =
let x = new MyClass()
for i in 1..100000 do
Console.WriteLine(x.MemoAddToOneSkip(i))
for i in 1..100000 do
Console.WriteLine(x.MemoAddToOne(i))
0
When you write this:
member this.MemoAddToOne = Memoize AddToOne
That's not a "value", but a property. A property in .NET is a pair of functions (get + set), but there are also read-only properties, which have only "get". And that's what you created here. They're basically functions in disguise.
So every time somebody accesses x.MemoAddToOne, they're basically calling a function, so every time the body is executed anew, thus making a new call to Memoize every time.
To avoid this, create the memoizers once and then return them from the property getter:
let memoAddToOne = Memoize AddToOne
member this.MemoAddToOne = memoAddToOne
Or use a shortcut for the same thing:
member val MemoAddToOne = Memoize AddToOne

Handle recursive function within an other function ocaml

If I have one or more recursive functions inside an Ocaml function how can I call them without exit from the main function taking their value as return of the main function?
I'm new in Ocaml so I'll try to explain me better...
If I have :
let function =
let rec recursive1 = ...
...
let rec recursive2 = ...
...
How can I call them inside function to tell it "Hey, do you see this recursive function? Now call it and takes its value."
Because my problem is that Ocaml as return of my functions sees Unit instead of the right return.
I will post the code below :
let change k v list_ =
let rec support k v list_ =
match list_ with
| [] -> []
| (i,value) :: tl -> if i = k
then (k,v) :: tl
else (i,value) :: support k v tl in
let inserted = support k v list_ in inserted
let () =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Change takes as input a key, a value and a (int * string )list and should return the same list of the input but changing the value linked to the key selected ( if in list ).
support, instead, makes the dirty job. It builds a new list and when k is found i = k it changes value and attach the tile, closing the function.
The return of change is unit when it should be (int * string) list. I think because inserted isn't taken as return of the function.
change does not return unit. The error in fact tells you exactly the opposite, that it returns (int * string) list but that it expects unit. And it expects unit because you're assigning it to a () pattern.
I don't know what you actually intend to do with the return value, as right now you don't seem to care about it, but you can fix the error by just assigning it to a name:
let result: (int * string) list =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Since it's not used I've added a type annotation to make sure we're getting what we expect here, as otherwise result could be anything and the compiler wouldn't complain. You don't typically need this if you're going to use result however, as you'd then get an error if the type doesn't unify with its usage.

How to get the name of a higher order function in F#? [duplicate]

How can I create a function called getFuncName that takes a function of type (unit -> 'a) and returns its name.
I was talking to one of the C# devs and they said you could use the .Method property on a Func type as shown in an example here.
I tried to convert this to F# :
for example convert (unit -> 'a) to a type Func<_> then call the property on it but it always returns the string "Invoke".
let getFuncName f =
let fFunc = System.Func<_>(fun _ -> f())
fFunc.Method.Name
let customFunc() = 1.0
// Returns "Invoke" but I want it to return "customFunc"
getFuncName customFunc
A bit of background to this problem is:
I have created an array of functions of type (unit -> Deedle.Frame). I now want to cycle through those functions invoking them and saving them to csv with the csv name having the same name as the function. Some hypothetical code is below:
let generators : (unit -> Frame<int, string>) array = ...
generators
|> Array.iter (fun generator -> generator().SaveCsv(sprintf "%s\%s.csv" __SOURCE_DIRECTORY__ (getFuncName generator)))
This is being used in a scripting sense rather than as application code.
Not sure how you searched for information, but the first query to the search engine gave me this response:
let getFuncName f =
let type' = f.GetType()
let method' = type'.GetMethods() |> Array.find (fun m -> m.Name="Invoke")
let il = method'.GetMethodBody().GetILAsByteArray()
let methodCodes = [byte OpCodes.Call.Value;byte OpCodes.Callvirt.Value]
let position = il |> Array.findIndex(fun x -> methodCodes |> List.exists ((=)x))
let metadataToken = BitConverter.ToInt32(il, position+1)
let actualMethod = type'.Module.ResolveMethod metadataToken
actualMethod.Name
Unfortunately, this code only works when F# compiler does not inline function body into calling method.
Taken from here
Although there may be a more simple way.

Function with an arbitrary number of arguments in F#

I want to write a function that will take an arbitrary number of (curried) arguments and simply print them out (or perform some other unspecified action with them). Here is what I have come up with:
let print arg =
let rec print args arg =
if not (FSharpType.IsFunction(typeof<'t>)) then
printfn "%A" args
Unchecked.defaultof<'t>
else
print (box arg::args)
print []
When I try to compile this I get the error The resulting type would be infinite when unifying ''t' and ''a -> 't.
I know I could just pass the arguments as a list, but I am trying to develop an API of sorts where this would be a useful idiom to have.
Is there some clever compiler trick to make such a function possible in F# or is it a lost cause?
It seems that the two branches of the inner print want to return different types: the "then" part wants to return 't, but the "else" part wants to return 'a -> 't, where 't is necessarily the same in both branches. That is, your function tries to return either its own return type or a function from another type to its own return type. Such combined return type would, indeed, be infinite, which is in perfect accordance with what you set out to do - namely, create a function with infinite number of arguments. Though I do not know how to formally prove it, I would say this is indeed impossible.
If your goal is to simply create a list of boxed values, you could get away with defining a few infix operators.
let (<+>) a b = a # [(box b)]
let (<&>) a b = [(box a); (box b)]
let xs = 5 <&> "abc" <+> 3.0 <+> None <+> true
>> val xs : obj list = [5; "abc"; 3.0; null; true]
Alternatively, with carefully chosen operator precedence, you can apply a function (but then you'll need a terminator):
let (^>) a b = (box a)::b
let (<&>) f xs = f xs
let print xs = sprintf "%A" xs
let xs = print <&> 5 ^> "abc" ^> 3.0 ^> None ^> true ^> []
>> val xs : string = "[5; "abc"; 3.0; null; true]"

OCaml: how to use user defined types as key for Map.Make?

I have the following code which I intend to create a Map with self defined types variable and location. I understand that the key type should be ordered (some comparator function). How shall I add these rules to make this work? Also, I find the code ugly here. Do I really need the ;; at the end of a type and module?
type variable = string;;
type location = int;;
module LocationMap = Map.Make(variable);;
module EnvironmentMap = Map.Make(location);;
EDIT
This is the rest of my code:
type variable = Variable of string
type location = Location of int
module LocationMap = Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap = Map.Make(struct type t = variable let compare = compare end)
(*file read function*)
let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
lines := input_line chan :: !lines
done;
!lines
with End_of_file ->
close_in chan;
List.rev !lines
in
(*get the inputs*)
let inputs = read_file Sys.argv.(1) in
for i = 0 to List.length inputs - 1 do
Printf.printf "%s\n" (List.nth inputs i)
done;
This has a syntax error. I am not sure why.
EDIT2
I make this work with the following edit:
type variable = Variable of string
type location = Location of int
module LocationMap = Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap = Map.Make(struct type t = variable let compare = compare end)
(*file read function*)
let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
lines := input_line chan :: !lines
done;
!lines
with End_of_file ->
close_in chan;
List.rev !lines
(*get the inputs*)
let () =
let inputs = read_file Sys.argv.(1) in
for i = 0 to List.length inputs - 1 do
Printf.printf "%s\n" (List.nth inputs i)
done;
Sorry for the long list of questions, what does let () = do here? Is it true that when I define a function with let, I do not need in?
When applying the Map.Make functor, you need to supply a struct containing your type and a compare function:
module LocationMap =
Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap =
Map.Make(struct type t = location let compare = compare end)
You never need to use ;; in compiled code. It's only required when using the toplevel, to tell it when it should evaluate what you've typed in so far.
Some people do use ;; in compiled code, but you never need to do this and I personally never do. There is always a way to get the same effect without using ;;.
Update
The let compare = compare binds the pre-existing OCaml function compare (the infamous polymorphic comparison function) to the name compare inside the struct. So, it creates a Map that uses polymorphic compare to do its comparisons. This is often what you want.
I created a file containing your definitions (without ;;) and the above code, then compiled it with ocamlc -c. There were no syntax errors. I'm positive you don't need to use ;;, as I've written many many thousands of lines of code without it.
Note that I'm not saying that if you remove ;; from syntactically correct OCaml code, the result is always syntactically correct. There are a few idioms that only work when you use ;;. I personally just avoid those idioms.
Update 2
A let at top level of a module is special, and doesn't have an in. It defines a global value of the module. OCaml treats every source file as a module (for free, as I like to say), with a name that's the same as the source file name (capitalized).
You can actually have any pattern in let pattern = expression. So let () = ... is completely normal. It just says that the expression has unit type (hence the pattern matches).

Resources