It follows the interface (trait) oriented programming style.
Created
November 30, 2021 15:25
-
-
Save lilac/65b004d64d0fb1e1746d04e14a32cdaf to your computer and use it in GitHub Desktop.
Implement method overriding of OOP in SML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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