/* A key-value index that can hold multiple types of value. * * Each element in the index is keyed by a TypeKey that has a type param that * matches the type of the value. */ concrete TypeTree { // Creates a new TypeTree, e.g., TypeTree$new(). @type new () -> (TypeTree) // Sets the value for the given key, inserting if necessary. @value set<#x> (TypeKey<#x>,#x) -> (TypeTree) // Removes the value for the given key. @value remove (TypeKey) -> (TypeTree) // Returns the value for the given key, or empty if: // - There is no entry for the key. // - The value for the key is not of type #x, e.g., was originally added to // the tree as a parent of type #x. @value get<#x> (TypeKey<#x>) -> (optional #x) } /* A typed key for indexing values in TypeTree. * * A key of type TypeKey<#x> indexes a value of type #x. The key can also be * used as a key for any parent type of #x. For example, if V -> I then * TypeKey can be used as TypeKey. */ concrete TypeKey<|#x> { // Note that TypeKey<#x> as a type argument for some #y can satisfy // // #y defines LessThan<#y> // // even though we only define LessThan>. // // This is non-trivial: // // - #x -> any, which is trivial. // - TypeKey<#x> -> TypeKey, since TypeKey has a single covariant param. // - LessThan> -> LessThan>, since LessThan has a // single contravariant param. // - TypeKey<#x> -> LessThan> -> LessThan>. // // This means that TypeKey<#x> can be used as a key in Tree. (See tree.0rp.) defines LessThan> defines Equals> // Creates a new TypeKey, e.g., TypeTree<#x>$new(). @type new () -> (TypeKey<#x>) }