a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts). http://homepages.inf.ed.ac.uk/wadler/papers/expression/expression.txt Expression Problem Extensibility
int | Add of e * e let rec eval = function | Int n -> n | Add (n, m) -> eval n + eval m let rec show = function | Int n -> sprintf “%d” n | Add (n, m) -> sprintf “(%s+%s)” (show n) (show m) 14
int | Add of e * e type e += Sub of e * e let rec eval = function | Int n -> n | Add (n, m) -> eval n + eval m | Sub (n, m) -> eval n – eval m let rec show = function | Int n -> sprintf “%d” n | Add (n, m) -> sprintf “(%s + %s)” (show n) (show m) | Sub (n, m) -> sprintf “(%s - %s)” (show n) (show m) 15 ࣈͷ෦ιʔείʔυͷ ฤूʹΑΔରԠ͕ඞཁ
-> n | Add (n, m) -> eval n + eval m let rec eval_sub = function | Sub (n, m) -> eval_sub n – eval_sub m | e -> eval e • ֦ுͨ͠෦͚ͩΛॲཧ͢Δखଓ͖ΛՃ • ֦ுͨ͠෦Ҏ֎ͷॲཧطଘͷखଓ͖ʹॲཧΛҕৡ ҕৡ
-> n | Add (n, m) -> eval n + eval m let rec eval_sub = function | Sub (n, m) -> eval_sub n – eval_sub m | e -> eval e • evalؔͷ࠶ؼݺͼग़͠Ҏ߱, eval_sub͕ؔݺΕͳ͍ • ͱͳΔྫAdd (Sub (Int 1, Int 2), Int 3) ҕৡ
function | Int n -> n | Add (n, m) -> this#eval n + this#eval m end class sub = object (this) inherit add_or_sub as super method eval = function | Sub (n, m) -> this#eval n – this#eval m | e -> super#eval e end ݱࡏͷखଓ͖ͰΧόʔ͠ͳ͍ཁૉʹॲཧΛҕৡ