Skip to content

Instantly share code, notes, and snippets.

@cthom06
Last active December 16, 2015 21:39
Show Gist options
  • Save cthom06/5501614 to your computer and use it in GitHub Desktop.
Save cthom06/5501614 to your computer and use it in GitHub Desktop.
Playing with laziness in f#
module LazyStuff.Main
open System
(* I dont know if this is actually fast *)
type FastLazy<'a> = {
mutable Value : 'a option;
Func : unit -> 'a;
}
with
member this.force () : 'a =
match this.Value with
| None ->
this.Value <- Some (this.Func ())
this.force ()
| Some v -> v
static member defer (f : unit -> 'a) =
{FastLazy.Func = f; Value = None}
end
type LazyMap<'key, 'value> when 'key : comparison =
| EmptyMap
| FullMap of FastLazy<('key * 'value) * LazyMap<'key, 'value> * LazyMap<'key, 'value>>
static member add (m : LazyMap<'key, 'value>) k v =
match m with
| EmptyMap -> FullMap (FastLazy.defer (fun () -> (k, v), EmptyMap, EmptyMap))
| FullMap m ->
FullMap (FastLazy.defer (fun () ->
let (ok, ov), l, r = m.force ()
if k <= ok then
(ok, ov), LazyMap.add l k v, r
else
(ok, ov), l, LazyMap.add r k v))
static member find (m : LazyMap<'key, 'value>) k =
match m with
| EmptyMap -> None
| FullMap lm ->
let (ok, ov), l, r = lm.force ()
if ok = k then
Some ov
else if ok < k then
LazyMap.find l k
else
LazyMap.find r k
static member empty = EmptyMap
static member debug (m : LazyMap<'key, 'value>) =
let rec inner m indent : string =
match m with
| EmptyMap -> indent + "*"
| FullMap m ->
let (k, v), l, r = m.force ()
(inner l (indent + "\t")) + "\n" + indent + " /\n" + indent + "(" + (k.ToString ()) + ", " + (v.ToString ()) + ")\n" + indent + " \\\n" + (inner r (indent + "\t"))
inner m ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment