Skip to content

Instantly share code, notes, and snippets.

@lilac
Created November 30, 2021 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lilac/65b004d64d0fb1e1746d04e14a32cdaf to your computer and use it in GitHub Desktop.
Save lilac/65b004d64d0fb1e1746d04e14a32cdaf to your computer and use it in GitHub Desktop.
Implement method overriding of OOP in SML

It follows the interface (trait) oriented programming style.

datatype CounterTrait = CounterTrait of {
get: CounterTrait -> int,
set: CounterTrait -> int -> unit,
inc: CounterTrait -> unit
}
fun unwrap (CounterTrait r) = r
datatype SimpleCounter = SimpleCounter of {
value: int ref,
trait: CounterTrait
}
datatype LogCounter = LogCounter of {
value: int ref,
trait: CounterTrait,
log: string -> unit
}
fun makeSimpleCounter (x: int) = let
val state = ref x
fun get _ = !state
fun set _ nv = state := nv
fun inc (trait : CounterTrait): unit = let
val CounterTrait r = trait
val current = #get r trait
val next = current + 1
in #set r trait next
end
val trait = CounterTrait {
get = get,
set = set,
inc = inc
}
in SimpleCounter {value = state, trait = trait}
end
fun log s = print (s ^ "\n")
fun makeLogCounter x = let
val SimpleCounter super = makeSimpleCounter x
(* val SimpleCounter {value = state, trait = trait} = super *)
val superTrait = #trait super
val CounterTrait r = superTrait
fun get _ = let
val v = #get r superTrait
val message = "Get value: " ^ (Int.toString v)
val _ = log message
in v
end
fun set _ nv = let
val _ = #set r superTrait nv
val message = "Set value to " ^ (Int.toString nv)
in log message
end
val trait = CounterTrait {
get = get,
set = set,
inc = #inc r
}
in LogCounter {value = #value super, trait = trait, log = log}
end
val lc = makeLogCounter 0
val i = ref 0
val limit = Int.fromString (hd (CommandLine.arguments ()))
val count = Option.getOpt (limit, 10)
val _ = while !i < count do let
val LogCounter r = lc
val trait = #trait r
in
#inc (unwrap trait) trait;
i := !i + 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment