mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 09:40:21 +00:00
76 lines
1.5 KiB
Standard ML
76 lines
1.5 KiB
Standard ML
|
|
structure LazyBase:> LAZY_BASE =
|
|
struct
|
|
type 'a lazy = unit -> 'a
|
|
|
|
exception Undefined
|
|
|
|
fun delay f = f
|
|
|
|
fun force f = f()
|
|
|
|
val undefined = fn () => raise Undefined
|
|
end
|
|
|
|
structure LazyMemoBase:> LAZY_BASE =
|
|
struct
|
|
|
|
datatype 'a susp = NotYet of unit -> 'a
|
|
| Done of 'a
|
|
|
|
type 'a lazy = unit -> 'a susp ref
|
|
|
|
exception Undefined
|
|
|
|
fun delay f =
|
|
let
|
|
val r = ref (NotYet f)
|
|
in
|
|
fn () => r
|
|
end
|
|
|
|
fun force f =
|
|
case f() of
|
|
ref (Done x) => x
|
|
| r as ref (NotYet f') =>
|
|
let
|
|
val a = f'()
|
|
in
|
|
r := Done a
|
|
; a
|
|
end
|
|
|
|
val undefined = fn () => raise Undefined
|
|
end
|
|
|
|
functor LazyFn(B: LAZY_BASE): LAZY' =
|
|
struct
|
|
|
|
open B
|
|
|
|
fun inject x = delay (fn () => x)
|
|
|
|
fun isUndefined x =
|
|
(ignore (force x)
|
|
; false)
|
|
handle Undefined => true
|
|
|
|
fun toString f x = if isUndefined x then "_|_" else f (force x)
|
|
|
|
fun eqBy p (x,y) = p(force x,force y)
|
|
fun eq (x,y) = eqBy op= (x,y)
|
|
fun compare p (x,y) = p(force x,force y)
|
|
|
|
structure Ops =
|
|
struct
|
|
val ! = force
|
|
val ? = inject
|
|
end
|
|
|
|
fun map f x = delay (fn () => f (force x))
|
|
|
|
end
|
|
|
|
structure Lazy' = LazyFn(LazyBase)
|
|
structure LazyMemo = LazyFn(LazyMemoBase)
|