diff --git a/Changelog.md b/Changelog.md index 6d0728475..228e6abe1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ * Add `PriorityQueue` (#392). * Add support for Weak references (#388). * Clarify difference between `List` and `pure/List` in doc comments (#386). +* **Breaking:** Rename `sort` to `sortInPlace`, add `sort` (#405). ## 1.0.0 diff --git a/mops.toml b/mops.toml index 9a2621957..39ba47408 100644 --- a/mops.toml +++ b/mops.toml @@ -20,8 +20,8 @@ matchers = "2.1.0" base-0-14-13 = "https://github.com/dfinity/motoko-base#moc-0.14.13@794174a307975c225cfb26b57f73e38a841c0415" [requirements] -moc = "0.16.1" +moc = "0.16.3-implicits-6" [toolchain] -moc = "0.16.1" +moc = "0.16.3-implicits-6" wasmtime = "35.0.0" diff --git a/src/Array.mo b/src/Array.mo index fd3ad44a9..ba5db9375 100644 --- a/src/Array.mo +++ b/src/Array.mo @@ -21,6 +21,8 @@ import Prim "mo:⛔"; module { + public type Self = [T]; + /// Creates an empty array (equivalent to `[]`). /// /// ```motoko include=import @@ -120,7 +122,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `equal` runs in O(1) time and space. - public func equal(array1 : [T], array2 : [T], equal : (T, T) -> Bool) : Bool { + public func equal(array1 : [T], array2 : [T], equal : (implicit : (T, T) -> Bool)) : Bool { let size1 = array1.size(); let size2 = array2.size(); if (size1 != size2) { @@ -221,7 +223,7 @@ module { /// /// Space: O(size) /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func sort(array : [T], compare : (T, T) -> Order.Order) : [T] { + public func sort(array : [T], compare : (implicit : (T, T) -> Order.Order)) : [T] { let varArray : [var T] = toVarArray(array); VarArray.sortInPlace(varArray, compare); fromVarArray(varArray) @@ -800,7 +802,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func indexOf(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat = nextIndexOf(array, equal, element, 0); + public func indexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = nextIndexOf(array, equal, element, 0); /// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive). /// @@ -817,7 +819,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func nextIndexOf(array : [T], equal : (T, T) -> Bool, element : T, fromInclusive : Nat) : ?Nat { + public func nextIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromInclusive : Nat) : ?Nat { var index = fromInclusive; let size = array.size(); while (index < size) { @@ -844,7 +846,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func lastIndexOf(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat = prevIndexOf(array, equal, element, array.size()); + public func lastIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = prevIndexOf(array, equal, element, array.size()); /// Returns the index of the previous occurence of `element` in the `array` starting from the `from` index (exclusive). /// @@ -864,7 +866,7 @@ module { /// /// Runtime: O(array.size()); /// Space: O(1); - public func prevIndexOf(array : [T], equal : (T, T) -> Bool, element : T, fromExclusive : Nat) : ?Nat { + public func prevIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromExclusive : Nat) : ?Nat { var i = fromExclusive; while (i > 0) { i -= 1; @@ -1030,7 +1032,7 @@ module { /// Space: O(size) /// /// *Runtime and space assumes that `f` runs in O(1) time and space. - public func toText(array : [T], f : T -> Text) : Text { + public func toText(array : [T], f : (implicit : (toText : T -> Text))) : Text { let size = array.size(); if (size == 0) { return "[]" }; var text = "["; @@ -1074,7 +1076,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func compare(array1 : [T], array2 : [T], compare : (T, T) -> Order.Order) : Order.Order { + public func compare(array1 : [T], array2 : [T], compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let size1 = array1.size(); let size2 = array2.size(); var i = 0; @@ -1112,7 +1114,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func binarySearch(array : [T], compare : (T, T) -> Order.Order, element : T) : { + public func binarySearch(array : [T], compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat } { diff --git a/src/Blob.mo b/src/Blob.mo index e9318e72c..522557672 100644 --- a/src/Blob.mo +++ b/src/Blob.mo @@ -38,6 +38,7 @@ import Order "Order"; module { public type Blob = Prim.Types.Blob; + public type Self = Blob; /// Returns an empty `Blob` (equivalent to `""`). /// diff --git a/src/Bool.mo b/src/Bool.mo index 45b0cee78..81934101b 100644 --- a/src/Bool.mo +++ b/src/Bool.mo @@ -31,6 +31,8 @@ module { /// Booleans with constants `true` and `false`. public type Bool = Prim.Types.Bool; + public type Self = Bool; + /// Returns `a and b`. /// /// Example: diff --git a/src/Char.mo b/src/Char.mo index c81ed9f91..fc290ac2a 100644 --- a/src/Char.mo +++ b/src/Char.mo @@ -31,6 +31,8 @@ module { /// Characters represented as Unicode code points. public type Char = Prim.Types.Char; + public type Self = Char; + /// Convert character `char` to a word containing its Unicode scalar value. /// /// Example: diff --git a/src/Error.mo b/src/Error.mo index b13d5279c..69d6dd3ec 100644 --- a/src/Error.mo +++ b/src/Error.mo @@ -9,6 +9,7 @@ module { /// Error value resulting from `async` computations public type Error = Prim.Types.Error; + public type Self = Error; /// Error code to classify different kinds of user and system errors: /// ```motoko diff --git a/src/Float.mo b/src/Float.mo index 7d79489d5..2eacf1337 100644 --- a/src/Float.mo +++ b/src/Float.mo @@ -54,6 +54,7 @@ module { /// 64-bit floating point number type. public type Float = Prim.Types.Float; + public type Self = Float; /// Ratio of the circumference of a circle to its diameter. /// Note: Limited precision. diff --git a/src/Int.mo b/src/Int.mo index e0aabb60c..8167252f2 100644 --- a/src/Int.mo +++ b/src/Int.mo @@ -18,6 +18,7 @@ module { /// Infinite precision signed integers. public type Int = Prim.Types.Int; + public type Self = Int; /// Returns the absolute value of `x`. /// diff --git a/src/Int16.mo b/src/Int16.mo index b423a56c5..acb4c1aa7 100644 --- a/src/Int16.mo +++ b/src/Int16.mo @@ -16,6 +16,7 @@ module { /// 16-bit signed integers. public type Int16 = Prim.Types.Int16; + public type Self = Int16; /// Minimum 16-bit integer value, `-2 ** 15`. /// diff --git a/src/Int32.mo b/src/Int32.mo index c9a4a122d..c7cfa43f6 100644 --- a/src/Int32.mo +++ b/src/Int32.mo @@ -15,6 +15,7 @@ module { /// 32-bit signed integers. public type Int32 = Prim.Types.Int32; + public type Self = Int32; /// Minimum 32-bit integer value, `-2 ** 31`. /// diff --git a/src/Int64.mo b/src/Int64.mo index 9744fba9f..634800089 100644 --- a/src/Int64.mo +++ b/src/Int64.mo @@ -16,6 +16,7 @@ module { /// 64-bit signed integers. public type Int64 = Prim.Types.Int64; + public type Self = Int64; /// Minimum 64-bit integer value, `-2 ** 63`. /// diff --git a/src/Int8.mo b/src/Int8.mo index 70519972f..7a986db85 100644 --- a/src/Int8.mo +++ b/src/Int8.mo @@ -15,6 +15,7 @@ module { /// 8-bit signed integers. public type Int8 = Prim.Types.Int8; + public type Self = Int8; /// Minimum 8-bit integer value, `-2 ** 7`. /// diff --git a/src/Iter.mo b/src/Iter.mo index 4d1d5a444..0bbf7f660 100644 --- a/src/Iter.mo +++ b/src/Iter.mo @@ -54,6 +54,7 @@ module { /// } /// ``` public type Iter = Types.Iter; + public type Self = Iter; /// Creates an empty iterator. /// @@ -531,7 +532,7 @@ module { /// let iter = [1, 2, 3, 4].values(); /// assert Iter.contains(iter, Nat.equal, 2); /// ``` - public func contains(iter : Iter, equal : (T, T) -> Bool, value : T) : Bool { + public func contains(iter : Iter, equal : (implicit : (T, T) -> Bool), value : T) : Bool { for (x in iter) { if (equal(x, value)) return true }; @@ -661,7 +662,7 @@ module { /// let iter = [1, 2, 3].values(); /// assert ?3 == Iter.max(iter, Nat.compare); /// ``` - public func max(iter : Iter, compare : (T, T) -> Order.Order) : ?T { + public func max(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : ?T { reduce( iter, func(a, b) { @@ -682,7 +683,7 @@ module { /// let iter = [1, 2, 3].values(); /// assert ?1 == Iter.min(iter, Nat.compare); /// ``` - public func min(iter : Iter, compare : (T, T) -> Order.Order) : ?T { + public func min(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : ?T { reduce( iter, func(a, b) { @@ -803,7 +804,7 @@ module { }; /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily. - public func sort(iter : Iter, compare : (T, T) -> Order.Order) : Iter { + public func sort(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : Iter { let array = toVarArray(iter); VarArray.sortInPlace(array, compare); fromVarArray(array) diff --git a/src/List.mo b/src/List.mo index 662d092b7..10d517705 100644 --- a/src/List.mo +++ b/src/List.mo @@ -32,6 +32,7 @@ module { /// /// The maximum number of elements in a `List` is 2^32. public type List = Types.List; + public type Self = List; let INTERNAL_ERROR = "List: internal error"; @@ -587,7 +588,7 @@ module { /// List.add(list, 3); /// List.add(list, 1); /// List.add(list, 2); - /// List.sort(list, Nat.compare); + /// List.sortInPlace(list, Nat.compare); /// assert List.toArray(list) == [1, 2, 3]; /// ``` /// @@ -595,7 +596,7 @@ module { /// /// Space: O(size) /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func sort(list : List, compare : (T, T) -> Order.Order) { + public func sortInPlace(list : List, compare : (implicit : (T, T) -> Order.Order)) { if (size(list) < 2) return; let arr = toVarArray(list); VarArray.sortInPlace(arr, compare); @@ -604,6 +605,31 @@ module { } }; + /// Sorts the elements in the list according to `compare`. + /// Sort is deterministic, stable, and in-place. + /// + /// Example: + /// ```motoko include=import + /// import Nat "mo:core/Nat"; + /// + /// let list = List.empty(); + /// List.add(list, 3); + /// List.add(list, 1); + /// List.add(list, 2); + /// let sorted = List.sort(list, Nat.compare); + /// assert List.toArray(sorted) == [1, 2, 3]; + /// ``` + /// + /// Runtime: O(size * log(size)) + /// + /// Space: O(size) + /// *Runtime and space assumes that `compare` runs in O(1) time and space. + public func sort(list : List, compare : (implicit : (T, T) -> Types.Order)) : List { + let array = toVarArray(list); + VarArray.sortInPlace(array, compare); + fromVarArray(array) + }; + /// Finds the first index of `element` in `list` using equality of elements defined /// by `equal`. Returns `null` if `element` is not found. /// @@ -624,7 +650,7 @@ module { /// Runtime: `O(size)` /// /// *Runtime and space assumes that `equal` runs in `O(1)` time and space. - public func indexOf(list : List, equal : (T, T) -> Bool, element : T) : ?Nat { + public func indexOf(list : List, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat { // inlining would save 10 instructions per entry findIndex(list, func(x) = equal(element, x)) }; @@ -645,7 +671,7 @@ module { /// Runtime: `O(size)` /// /// *Runtime and space assumes that `equal` runs in `O(1)` time and space. - public func lastIndexOf(list : List, equal : (T, T) -> Bool, element : T) : ?Nat { + public func lastIndexOf(list : List, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat { // inlining would save 10 instructions per entry findLastIndex(list, func(x) = equal(element, x)) }; @@ -784,7 +810,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `compare` runs in `O(1)` time and space. - public func binarySearch(list : List, compare : (T, T) -> Order.Order, element : T) : { + public func binarySearch(list : List, compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat } { @@ -1547,7 +1573,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `equal` runs in O(1) time and space. - public func contains(list : List, equal : (T, T) -> Bool, element : T) : Bool { + public func contains(list : List, equal : (implicit : (T, T) -> Bool), element : T) : Bool { Option.isSome(indexOf(list, equal, element)) }; @@ -1571,7 +1597,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func max(list : List, compare : (T, T) -> Order.Order) : ?T { + public func max(list : List, compare : (implicit : (T, T) -> Order.Order)) : ?T { if (isEmpty(list)) return null; var maxSoFar = at(list, 0); @@ -1606,7 +1632,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func min(list : List, compare : (T, T) -> Order.Order) : ?T { + public func min(list : List, compare : (implicit : (T, T) -> Order.Order)) : ?T { if (isEmpty(list)) return null; var minSoFar = at(list, 0); @@ -1642,7 +1668,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `equal` runs in O(1) time and space. - public func equal(list1 : List, list2 : List, equal : (T, T) -> Bool) : Bool { + public func equal(list1 : List, list2 : List, equal : (implicit : (T, T) -> Bool)) : Bool { let size1 = size(list1); if (size1 != size(list2)) return false; @@ -1680,7 +1706,7 @@ module { /// Space: `O(1)` /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func compare(list1 : List, list2 : List, compare : (T, T) -> Order.Order) : Order.Order { + public func compare(list1 : List, list2 : List, compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let size1 = size(list1); let size2 = size(list2); let minSize = if (size1 < size2) { size1 } else { size2 }; @@ -1716,7 +1742,7 @@ module { /// Space: `O(size)` /// /// *Runtime and space assumes that `toText` runs in O(1) time and space. - public func toText(list : List, f : T -> Text) : Text { + public func toText(list : List, f : (implicit : (toText : T -> Text))) : Text { let vsize : Int = size(list); let next = values_(list).unsafe_next; var i = 0; diff --git a/src/Map.mo b/src/Map.mo index 73d1fd061..cf98cb21d 100644 --- a/src/Map.mo +++ b/src/Map.mo @@ -35,6 +35,7 @@ import PureMap "pure/Map"; import Types "Types"; +import Iter "Iter"; import Order "Order"; import VarArray "VarArray"; import Runtime "Runtime"; @@ -46,6 +47,7 @@ module { let btreeOrder = 32; // Should be >= 4 and <= 512. public type Map = Types.Map; + public type Self = Map; type Node = Types.Map.Node; type Data = Types.Map.Data; @@ -75,7 +77,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func toPure(map : Map, compare : (K, K) -> Order.Order) : PureMap.Map { + public func toPure(map : Map, compare : (implicit : (K, K) -> Order.Order)) : PureMap.Map { PureMap.fromIter(entries(map), compare) }; @@ -100,7 +102,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func fromPure(map : PureMap.Map, compare : (K, K) -> Order.Order) : Map { + public func fromPure(map : PureMap.Map, compare : (implicit : (K, K) -> Order.Order)) : Map { fromIter(PureMap.entries(map), compare) }; @@ -279,7 +281,7 @@ module { /// /// Runtime: `O(n)`. /// Space: `O(1)`. - public func equal(map1 : Map, map2 : Map, compareKey : (K, K) -> Types.Order, equalValue : (V, V) -> Bool) : Bool { + public func equal(map1 : Map, map2 : Map, compare : (implicit : (K, K) -> Types.Order), equal : (implicit : (V, V) -> Bool)) : Bool { if (size(map1) != size(map2)) { return false }; @@ -294,8 +296,8 @@ module { }; case (?(key1, value1), ?(key2, value2)) { if ( - not (compareKey(key1, key2) == #equal) or - not equalValue(value1, value2) + not (compare(key1, key2) == #equal) or + not equal(value1, value2) ) { return false } @@ -326,7 +328,7 @@ module { /// Space: `O(1)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func containsKey(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool { + public func containsKey(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool { Option.isSome(get(map, compare, key)) }; @@ -351,7 +353,7 @@ module { /// Space: `O(1)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func get(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V { + public func get(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V { switch (map.root) { case (#internal(internalNode)) { getFromInternal(internalNode, compare, key) @@ -384,7 +386,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func insert(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : Bool { + public func insert(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : Bool { switch (swap(map, compare, key, value)) { case null true; case _ false @@ -415,7 +417,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func add(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) { + public func add(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) { ignore swap(map, compare, key, value) }; @@ -444,7 +446,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func swap(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : ?V { + public func swap(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : ?V { let insertResult = switch (map.root) { case (#leaf(leafNode)) { leafInsertHelper(leafNode, btreeOrder, compare, key, value) @@ -509,7 +511,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func replace(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : ?V { + public func replace(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : ?V { // TODO: Could be optimized in future if (containsKey(map, compare, key)) { swap(map, compare, key, value) @@ -544,7 +546,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` objects that will be collected as garbage. - public func remove(map : Map, compare : (K, K) -> Order.Order, key : K) { + public func remove(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) { ignore delete(map, compare, key) }; @@ -575,7 +577,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` objects that will be collected as garbage. - public func delete(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool { + public func delete(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool { switch (take(map, compare, key)) { case null false; case _ true @@ -609,7 +611,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` objects that will be collected as garbage. - public func take(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V { + public func take(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V { let deletedValue = switch (map.root) { case (#leaf(leafNode)) { // TODO: think about how this can be optimized so don't have to do two steps (search and then insert)? @@ -654,6 +656,14 @@ module { deletedValue }; + public func toArray(map : Map) : [(K, V)] { + Iter.toArray(entries(map)) + }; + + public func toVarArray(map : Map) : [var (K, V)] { + Iter.toVarArray(entries(map)) + }; + /// Retrieves the key-value pair from the map with the maximum key. /// If the map is empty, returns `null`. /// @@ -766,7 +776,7 @@ module { /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. public func entriesFrom( map : Map, - compare : (K, K) -> Order.Order, + compare : (implicit : (K, K) -> Order.Order), key : K ) : Types.Iter<(K, V)> { switch (map.root) { @@ -831,7 +841,7 @@ module { /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. public func reverseEntriesFrom( map : Map, - compare : (K, K) -> Order.Order, + compare : (implicit : (K, K) -> Order.Order), key : K ) : Types.Iter<(K, V)> { switch (map.root) { @@ -924,7 +934,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of key-value entries returned by the iterator and /// assuming that the `compare` function implements an `O(1)` comparison. - public func fromIter(iter : Types.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map { + public func fromIter(iter : Types.Iter<(K, V)>, compare : (implicit : (K, K) -> Order.Order)) : Map { let map = empty(); for ((key, value) in iter) { add(map, compare, key, value) @@ -932,6 +942,14 @@ module { map }; + public func fromArray(array : [(K, V)], compare : (implicit : (K, K) -> Order.Order)) : Map { + fromIter(array.values(), compare) + }; + + public func fromVarArray(array : [var (K, V)], compare : (implicit : (K, K) -> Order.Order)) : Map { + fromIter(array.values(), compare) + }; + /// Apply an operation on each key-value pair contained in the map. /// The operation is applied in ascending order of the keys. /// @@ -989,7 +1007,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func filter(map : Map, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map { + public func filter(map : Map, compare : (implicit : (K, K) -> Order.Order), criterion : (K, V) -> Bool) : Map { let result = empty(); for ((key, value) in entries(map)) { if (criterion(key, value)) { @@ -1195,7 +1213,7 @@ module { /// where `n` denotes the number of key-value entries stored in the map. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func filterMap(map : Map, compare : (K, K) -> Order.Order, project : (K, V1) -> ?V2) : Map { + public func filterMap(map : Map, compare : (implicit : (K, K) -> Order.Order), project : (K, V1) -> ?V2) : Map { let result = empty(); for ((key, value1) in entries(map)) { switch (project(key, value1)) { @@ -1209,7 +1227,7 @@ module { /// Internal sanity check function. /// Can be used to check that key/value pairs have been inserted with a consistent key comparison function. /// Traps if the internal map structure is invalid. - public func assertValid(map : Map, compare : (K, K) -> Order.Order) { + public func assertValid(map : Map, compare : (implicit : (K, K) -> Order.Order)) { func checkIteration(iterator : Types.Iter<(K, V)>, order : Order.Order) { switch (iterator.next()) { case null {}; @@ -1254,7 +1272,7 @@ module { /// assuming that `keyFormat` and `valueFormat` have runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func toText(map : Map, keyFormat : K -> Text, valueFormat : V -> Text) : Text { + public func toText(map : Map, keyFormat : (implicit : (toText : K -> Text)), valueFormat : (implicit : (toText : V -> Text))) : Text { var text = "Map{"; var sep = ""; for ((key, value) in entries(map)) { @@ -1305,7 +1323,7 @@ module { /// assuming that `compareKey` and `compareValue` have runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func compare(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order { + public func compare(map1 : Map, map2 : Map, compareKey : (implicit : (compare : (K, K) -> Order.Order)), compareValue : (implicit : (compare : (V, V) -> Order.Order))) : Order.Order { let iterator1 = entries(map1); let iterator2 = entries(map2); loop { @@ -2308,7 +2326,7 @@ module { /// * compare - the comparator used to perform the search /// * searchKey - the key being compared against in the search /// * maxIndex - the right-most index (bound) from which to begin the search - public func binarySearchNode(array : [var ?(K, V)], compare : (K, K) -> Order.Order, searchKey : K, maxIndex : Nat) : SearchResult { + public func binarySearchNode(array : [var ?(K, V)], compare : (implicit : (K, K) -> Order.Order), searchKey : K, maxIndex : Nat) : SearchResult { // TODO: get rid of this check? // Trap if array is size 0 (should not happen) if (array.size() == 0) { diff --git a/src/Nat.mo b/src/Nat.mo index 560aba056..b19e957a6 100644 --- a/src/Nat.mo +++ b/src/Nat.mo @@ -19,6 +19,7 @@ module { /// Infinite precision natural numbers. public type Nat = Prim.Types.Nat; + public type Self = Nat; /// Converts a natural number to its textual representation. Textual /// representation _do not_ contain underscores to represent commas. diff --git a/src/Nat16.mo b/src/Nat16.mo index ecd8b600f..31996cd0b 100644 --- a/src/Nat16.mo +++ b/src/Nat16.mo @@ -15,6 +15,7 @@ module { /// 16-bit natural numbers. public type Nat16 = Prim.Types.Nat16; + public type Self = Nat16; /// Maximum 16-bit natural number. `2 ** 16 - 1`. /// diff --git a/src/Nat32.mo b/src/Nat32.mo index 05bac731b..354a9d60f 100644 --- a/src/Nat32.mo +++ b/src/Nat32.mo @@ -15,6 +15,7 @@ module { /// 32-bit natural numbers. public type Nat32 = Prim.Types.Nat32; + public type Self = Nat32; /// Maximum 32-bit natural number. `2 ** 32 - 1`. /// diff --git a/src/Nat64.mo b/src/Nat64.mo index 3539b2743..0834b41be 100644 --- a/src/Nat64.mo +++ b/src/Nat64.mo @@ -15,6 +15,7 @@ module { /// 64-bit natural numbers. public type Nat64 = Prim.Types.Nat64; + public type Self = Nat64; /// Maximum 64-bit natural number. `2 ** 64 - 1`. /// diff --git a/src/Nat8.mo b/src/Nat8.mo index bb0dc4f83..1b7cb106e 100644 --- a/src/Nat8.mo +++ b/src/Nat8.mo @@ -15,6 +15,7 @@ module { /// 8-bit natural numbers. public type Nat8 = Prim.Types.Nat8; + public type Self = Nat8; /// Maximum 8-bit natural number. `2 ** 8 - 1`. /// diff --git a/src/Option.mo b/src/Option.mo index def91a027..2293a027c 100644 --- a/src/Option.mo +++ b/src/Option.mo @@ -29,6 +29,8 @@ import Types "Types"; module { + public type Self = ?T; + /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and /// `get(null, d) = d`. public func get(x : ?T, default : T) : T = switch x { @@ -38,7 +40,7 @@ module { /// Unwraps an optional value using a function, or returns the default, i.e. /// `option(?x, f, d) = f x` and `option(null, f, d) = d`. - public func getMapped(x : ?A, f : A -> B, default : B) : B = switch x { + public func getMapped(x : ?T, f : T -> R, default : R) : R = switch x { case null { default }; case (?x_) { f(x_) } }; @@ -49,7 +51,7 @@ module { /// assert Option.map(?42, func x = x + 1) == ?43; /// assert Option.map(null, func x = x + 1) == null; /// ``` - public func map(x : ?A, f : A -> B) : ?B = switch x { + public func map(x : ?T, f : T -> R) : ?R = switch x { case null { null }; case (?x_) { ?f(x_) } }; @@ -65,14 +67,14 @@ module { /// Option.forEach(null, func (x : Nat) { counter += x }); /// assert counter == 5; /// ``` - public func forEach(x : ?A, f : A -> ()) = switch x { + public func forEach(x : ?T, f : T -> ()) = switch x { case null {}; case (?x_) { f(x_) } }; /// Applies an optional function to an optional value. Returns `null` if at /// least one of the arguments is `null`. - public func apply(x : ?A, f : ?(A -> B)) : ?B { + public func apply(x : ?T, f : ?(T -> R)) : ?R { switch (f, x) { case (?f_, ?x_) { ?f_(x_) }; case (_, _) { null } @@ -81,7 +83,7 @@ module { /// Applies a function to an optional value. Returns `null` if the argument is /// `null`, or the function returns `null`. - public func chain(x : ?A, f : A -> ?B) : ?B { + public func chain(x : ?T, f : T -> ?R) : ?R { switch (x) { case (?x_) { f(x_) }; case (null) { null } @@ -95,8 +97,8 @@ module { /// assert Option.flatten(?(null)) == null; /// assert Option.flatten(null) == null; /// ``` - public func flatten(x : ??A) : ?A { - chain(x, func(x_ : ?A) : ?A = x_) + public func flatten(x : ??T) : ?T { + chain(x, func(x_ : ?T) : ?T = x_) }; /// Creates an optional value from a definite value. @@ -104,7 +106,7 @@ module { /// import Option "mo:core/Option"; /// assert Option.some(42) == ?42; /// ``` - public func some(x : A) : ?A = ?x; + public func some(x : T) : ?T = ?x; /// Returns true if the argument is not `null`, otherwise returns false. public func isSome(x : ?Any) : Bool { @@ -117,7 +119,7 @@ module { }; /// Returns true if the optional arguments are equal according to the equality function provided, otherwise returns false. - public func equal(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool = switch (x, y) { + public func equal(x : ?T, y : ?T, eq : (implicit : (equal : (T, T) -> Bool))) : Bool = switch (x, y) { case (null, null) { true }; case (?x_, ?y_) { eq(x_, y_) }; case (_, _) { false } @@ -130,7 +132,7 @@ module { /// - `#less` if the first value is `null` and the second is not, /// - `#greater` if the first value is not `null` and the second is, /// - the result of the comparison function when both values are not `null`. - public func compare(x : ?A, y : ?A, cmp : (A, A) -> Types.Order) : Types.Order = switch (x, y) { + public func compare(x : ?T, y : ?T, cmp : (implicit : (compare : (T, T) -> Types.Order))) : Types.Order = switch (x, y) { case (null, null) #equal; case (null, _) #less; case (_, null) #greater; @@ -146,7 +148,7 @@ module { }; /// Returns the textural representation of an optional value for debugging purposes. - public func toText(x : ?A, toText : A -> Text) : Text = switch x { + public func toText(x : ?T, toText : (implicit : T -> Text)) : Text = switch x { case null { "null" }; case (?x_) { "?" # toText(x_) } }; diff --git a/src/Order.mo b/src/Order.mo index d6b84b095..080bd104d 100644 --- a/src/Order.mo +++ b/src/Order.mo @@ -6,6 +6,7 @@ module { /// A type to represent an order. public type Order = Types.Order; + public type Self = Order; /// Check if an order is #less. public func isLess(order : Order) : Bool { diff --git a/src/Principal.mo b/src/Principal.mo index 5bf76b99c..5b5f1d469 100644 --- a/src/Principal.mo +++ b/src/Principal.mo @@ -39,6 +39,7 @@ import Types "Types"; module { public type Principal = Prim.Types.Principal; + public type Self = Principal; /// Get the `Principal` identifier of an actor. /// diff --git a/src/PriorityQueue.mo b/src/PriorityQueue.mo index eaaa95a4e..3fe262cd8 100644 --- a/src/PriorityQueue.mo +++ b/src/PriorityQueue.mo @@ -38,7 +38,6 @@ import List "List"; import Types "Types"; import Order "Order"; -import Prim "mo:⛔"; module { public type PriorityQueue = Types.PriorityQueue; @@ -131,14 +130,14 @@ module { /// Runtime: `O(log n)`. Space: `O(1)`. public func push( priorityQueue : PriorityQueue, - compare : (T, T) -> Order.Order, + compare : (implicit : (T, T) -> Order.Order), element : T ) { let heap = priorityQueue.heap; List.add(heap, element); - var index = List.size(heap) - 1; + var index : Nat = List.size(heap) - 1; while (index > 0) { - let parentId = (index - 1) / 2; + let parentId = (index - 1) : Nat / 2; let parentVal = List.at(heap, parentId); if (compare(element, parentVal) == #greater) { List.put(heap, index, parentVal); @@ -184,14 +183,14 @@ module { /// Runtime: `O(log n)`. Space: `O(1)`. public func pop( priorityQueue : PriorityQueue, - compare : (T, T) -> Order.Order + compare : (implicit : (T, T) -> Order.Order) ) : ?T { let heap = priorityQueue.heap; if (List.isEmpty(heap)) { return null }; let top = List.get(heap, 0); - let lastIndex = List.size(heap) - 1; + let lastIndex : Nat = List.size(heap) - 1; let lastElem = List.at(heap, lastIndex); var index = 0; diff --git a/src/Queue.mo b/src/Queue.mo index 8e61fff06..36b5d63fc 100644 --- a/src/Queue.mo +++ b/src/Queue.mo @@ -38,6 +38,7 @@ import Prim "mo:⛔"; module { public type Queue = Types.Queue.Queue; + public type Self = Queue; type Node = Types.Queue.Node; @@ -232,7 +233,7 @@ module { /// Runtime: O(n) /// Space: O(1) /// `n` denotes the number of elements stored in the queue. - public func contains(queue : Queue, equal : (T, T) -> Bool, element : T) : Bool { + public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), element : T) : Bool { for (existing in values(queue)) { if (equal(existing, element)) { return true @@ -461,6 +462,10 @@ module { queue }; + public func fromVarArray(array : [var T]) : Queue { + fromIter(array.values()) + }; + /// Creates a new immutable array containing all elements from the queue. /// Elements appear in the same order as in the queue (front to back). /// @@ -492,6 +497,10 @@ module { ) }; + public func toVarArray(queue : Queue) : [var T] { + Array.toVarArray(toArray(queue)) + }; + /// Returns an iterator over the elements in the queue. /// Iterates from front to back. /// @@ -526,6 +535,10 @@ module { } }; + public func reverseValues(queue : Queue) : Iter.Iter { + Iter.reverse(values(queue)) + }; + /// Tests whether all elements in the queue satisfy the given predicate. /// /// Example: @@ -696,7 +709,7 @@ module { /// Runtime: O(n) /// Space: O(1) /// `n` denotes the number of elements stored in the queue. - public func equal(queue1 : Queue, queue2 : Queue, equal : (T, T) -> Bool) : Bool { + public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool { if (size(queue1) != size(queue2)) { return false }; @@ -735,7 +748,7 @@ module { /// Runtime: O(n) /// Space: O(n) /// `n` denotes the number of elements stored in the queue. - public func toText(queue : Queue, format : T -> Text) : Text { + public func toText(queue : Queue, format : (implicit : (toText : T -> Text))) : Text { var text = "Queue["; var sep = ""; for (element in values(queue)) { @@ -764,7 +777,7 @@ module { /// Runtime: O(n) /// Space: O(1) /// `n` denotes the number of elements stored in the queue. - public func compare(queue1 : Queue, queue2 : Queue, compare : (T, T) -> Order.Order) : Order.Order { + public func compare(queue1 : Queue, queue2 : Queue, compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let iterator1 = values(queue1); let iterator2 = values(queue2); loop { diff --git a/src/Result.mo b/src/Result.mo index 68d579354..44feb1240 100644 --- a/src/Result.mo +++ b/src/Result.mo @@ -44,6 +44,7 @@ module { /// assert validateEmail("user@invalid") == #err("Invalid domain format"); /// ``` public type Result = Types.Result; + public type Self = Result; /// Compares two Results for equality. /// @@ -62,8 +63,8 @@ module { public func equal( result1 : Result, result2 : Result, - equalOk : (Ok, Ok) -> Bool, - equalErr : (Err, Err) -> Bool + equalOk : (implicit : (equal : Ok, Ok) -> Bool), + equalErr : (implicit : (equal : (Err, Err) -> Bool)) ) : Bool { switch (result1, result2) { case (#ok(ok1), #ok(ok2)) { @@ -95,8 +96,8 @@ module { public func compare( result1 : Result, result2 : Result, - compareOk : (Ok, Ok) -> Order.Order, - compareErr : (Err, Err) -> Order.Order + compareOk : (implicit : (compare : (Ok, Ok) -> Order.Order)), + compareErr : (implicit : (compare : (Err, Err) -> Order.Order)) ) : Order.Order { switch (result1, result2) { case (#ok(ok1), #ok(ok2)) { diff --git a/src/Set.mo b/src/Set.mo index d50a48efb..e694e53cc 100644 --- a/src/Set.mo +++ b/src/Set.mo @@ -44,6 +44,7 @@ module { let btreeOrder = 32; // Should be >= 4 and <= 512. public type Set = Types.Set.Set; + public type Self = Set; type Node = Types.Set.Node; type Data = Types.Set.Data; type Internal = Types.Set.Internal; @@ -71,7 +72,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func toPure(set : Set, compare : (T, T) -> Order.Order) : PureSet.Set { + public func toPure(set : Set, compare : (implicit : (T, T) -> Order.Order)) : PureSet.Set { PureSet.fromIter(values(set), compare) }; @@ -95,10 +96,14 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func fromPure(set : PureSet.Set, compare : (T, T) -> Order.Order) : Set { + public func fromPure(set : PureSet.Set, compare : (implicit : (T, T) -> Order.Order)) : Set { fromIter(PureSet.values(set), compare) }; + public func fromArray(array : [T], compare : (implicit : (T, T) -> Order.Order)) : Set { + fromIter(array.values(), compare) + }; + /// Create a copy of the mutable set. /// /// Example: @@ -270,7 +275,7 @@ module { /// /// Runtime: `O(n)`. /// Space: `O(1)`. - public func equal(set1 : Set, set2 : Set, compare : (T, T) -> Types.Order) : Bool { + public func equal(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Types.Order)) : Bool { if (set1.size != set2.size) return false; // TODO: optimize let iterator1 = values(set1); @@ -314,7 +319,7 @@ module { /// Space: `O(1)`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func contains(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool { + public func contains(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool { switch (set.root) { case (#internal(internalNode)) { containsInInternal(internalNode, compare, element) @@ -345,7 +350,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func add(set : Set, compare : (T, T) -> Order.Order, element : T) { + public func add(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) { ignore insert(set, compare, element) }; @@ -371,7 +376,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func insert(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool { + public func insert(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool { let insertResult = switch (set.root) { case (#leaf(leafNode)) { leafInsertHelper(leafNode, btreeOrder, compare, element) @@ -435,7 +440,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` objects that will be collected as garbage. - public func remove(set : Set, compare : (T, T) -> Order.Order, element : T) : () { + public func remove(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : () { ignore delete(set, compare, element) }; @@ -465,7 +470,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` objects that will be collected as garbage. - public func delete(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool { + public func delete(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool { let deleted = switch (set.root) { case (#leaf(leafNode)) { // TODO: think about how this can be optimized so don't have to do two steps (search and then insert)? @@ -560,6 +565,10 @@ module { values(set).next() }; + public func toArray(set : Set) : [T] { + Iter.toArray(values(set)) + }; + /// Returns an iterator over the elements in the set, /// traversing the elements in the ascending order. /// @@ -614,7 +623,7 @@ module { /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. public func valuesFrom( set : Set, - compare : (T, T) -> Order.Order, + compare : (implicit : (T, T) -> Order.Order), element : T ) : Types.Iter { switch (set.root) { @@ -677,7 +686,7 @@ module { /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. public func reverseValuesFrom( set : Set, - compare : (T, T) -> Order.Order, + compare : (implicit : (T, T) -> Order.Order), element : T ) : Types.Iter { switch (set.root) { @@ -706,7 +715,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of elements returned by the iterator and /// assuming that the `compare` function implements an `O(1)` comparison. - public func fromIter(iter : Types.Iter, compare : (T, T) -> Order.Order) : Set { + public func fromIter(iter : Types.Iter, compare : (implicit : (T, T) -> Order.Order)) : Set { let set = empty(); for (element in iter) { add(set, compare, element) @@ -735,7 +744,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func isSubset(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Bool { + public func isSubset(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool { if (set1.size > set2.size) { return false }; // TODO: optimize for (element in values(set1)) { @@ -769,7 +778,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func union(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func union(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { let result = clone(set1); for (element in values(set2)) { if (not contains(result, compare, element)) { @@ -800,7 +809,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func intersection(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func intersection(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { let result = empty(); for (element in values(set1)) { if (contains(set2, compare, element)) { @@ -831,7 +840,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func difference(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func difference(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { let result = empty(); for (element in values(set1)) { if (not contains(set2, compare, element)) { @@ -861,7 +870,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func addAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter) { + public func addAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter) { for (element in iter) { add(set, compare, element) } @@ -888,7 +897,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func deleteAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter) : Bool { + public func deleteAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter) : Bool { var deleted = false; for (element in iter) { deleted := delete(set, compare, element) or deleted // order matters! @@ -918,7 +927,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func insertAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter) : Bool { + public func insertAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter) : Bool { var inserted = false; for (element in iter) { inserted := insert(set, compare, element) or inserted // order matters! @@ -944,7 +953,7 @@ module { /// assert sizeChanged; /// } /// ``` - public func retainAll(set : Set, compare : (T, T) -> Order.Order, predicate : T -> Bool) : Bool { + public func retainAll(set : Set, compare : (implicit : (T, T) -> Order.Order), predicate : T -> Bool) : Bool { let array = Array.fromIter(values(set)); deleteAll( set, @@ -1007,7 +1016,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func filter(set : Set, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set { + public func filter(set : Set, compare : (implicit : (T, T) -> Order.Order), criterion : T -> Bool) : Set { let result = empty(); for (element in values(set)) { if (criterion(element)) { @@ -1043,7 +1052,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func map(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set { + public func map(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> T2) : Set { let result = empty(); for (element1 in values(set)) { let element2 = project(element1); @@ -1083,7 +1092,7 @@ module { /// where `n` denotes the number of elements stored in the set. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func filterMap(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set { + public func filterMap(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> ?T2) : Set { let result = empty(); for (element1 in values(set)) { switch (project(element1)) { @@ -1198,7 +1207,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `n` denotes the number of elements stored in the iterated sets, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func join(setIterator : Types.Iter>, compare : (T, T) -> Order.Order) : Set { + public func join(setIterator : Types.Iter>, compare : (implicit : (T, T) -> Order.Order)) : Set { let result = empty(); for (set in setIterator) { for (element in values(set)) { @@ -1240,7 +1249,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `n` denotes the number of elements stored in all the sub-sets, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func flatten(setOfSets : Set>, compare : (T, T) -> Order.Order) : Set { + public func flatten(setOfSets : Set>, compare : (implicit : (T, T) -> Order.Order)) : Set { let result = empty(); for (subSet in values(setOfSets)) { for (element in values(subSet)) { @@ -1321,7 +1330,7 @@ module { /// Internal sanity check function. /// Can be used to check that elements have been inserted with a consistent comparison function. /// Traps if the internal set structure is invalid. - public func assertValid(set : Set, compare : (T, T) -> Order.Order) { + public func assertValid(set : Set, compare : (implicit : (T, T) -> Order.Order)) { func checkIteration(iterator : Types.Iter, order : Order.Order) { switch (iterator.next()) { case null {}; @@ -1367,11 +1376,11 @@ module { /// assuming that `elementFormat` has runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func toText(set : Set, elementFormat : T -> Text) : Text { + public func toText(set : Set, toText : (implicit : T -> Text)) : Text { var text = "Set{"; var sep = ""; for (element in values(set)) { - text #= sep # elementFormat(element); + text #= sep # toText(element); sep := ", " }; text # "}" @@ -1413,7 +1422,7 @@ module { /// assuming that `compare` has runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func compare(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Order.Order { + public func compare(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let iterator1 = values(set1); let iterator2 = values(set2); loop { diff --git a/src/Stack.mo b/src/Stack.mo index cc570a2f3..aca305a69 100644 --- a/src/Stack.mo +++ b/src/Stack.mo @@ -29,12 +29,14 @@ // TODO: optimize or re-use pure/List operations (e.g. for `any` etc) import Order "Order"; +import Iter "Iter"; import Types "Types"; import PureList "pure/List"; module { type List = Types.Pure.List; public type Stack = Types.Stack; + public type Self = Stack; /// Convert a mutable stack to an immutable, purely functional list. /// Please note that functional lists are ordered like stacks (FIFO). @@ -62,6 +64,14 @@ module { stack.top }; + public func toArray(stack : Stack) : [T] { + values(stack).toArray() + }; + + public func toVarArray(stack : Stack) : [var T] { + values(stack).toVarArray() + }; + /// Convert an immutable, purely functional list to a mutable stack. /// Please note that functional lists are ordered like stacks (FIFO). /// @@ -97,6 +107,14 @@ module { } }; + public func fromVarArray(array : [var T]) : Stack { + fromIter(array.values()) + }; + + public func fromArray(array : [T]) : Stack { + fromIter(array.values()) + }; + /// Create a new empty mutable stack. /// /// Example: @@ -269,7 +287,7 @@ module { /// Space: O(1) /// where `n` denotes the number of elements stored on the stack and assuming /// that `equal` has O(1) costs. - public func contains(stack : Stack, equal : (T, T) -> Bool, element : T) : Bool { + public func contains(stack : Stack, equal : (implicit : (T, T) -> Bool), element : T) : Bool { for (existing in values(stack)) { if (equal(existing, element)) { return true @@ -278,6 +296,10 @@ module { false }; + public func reverseValues(stack : Stack) : Iter.Iter { + values(stack).reverse() + }; + /// Pushes a new element onto the top of the stack. /// /// Example: @@ -673,7 +695,7 @@ module { /// Space: O(1) /// where `n` denotes the number of elements stored on the stack and /// assuming that `equal` has O(1) costs. - public func equal(stack1 : Stack, stack2 : Stack, equal : (T, T) -> Bool) : Bool { + public func equal(stack1 : Stack, stack2 : Stack, equal : (implicit : (T, T) -> Bool)) : Bool { if (size(stack1) != size(stack2)) { return false }; @@ -740,7 +762,7 @@ module { /// Space: O(n) /// where `n` denotes the number of elements stored on the stack and /// assuming that `format` has O(1) costs. - public func toText(stack : Stack, format : T -> Text) : Text { + public func toText(stack : Stack, format : (implicit : (toText : T -> Text))) : Text { var text = "Stack["; var sep = ""; for (element in values(stack)) { @@ -769,7 +791,7 @@ module { /// Space: O(1) /// where `n` denotes the number of elements stored on the stack and /// assuming that `compare` has O(1) costs. - public func compare(stack1 : Stack, stack2 : Stack, compare : (T, T) -> Order.Order) : Order.Order { + public func compare(stack1 : Stack, stack2 : Stack, compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let iterator1 = values(stack1); let iterator2 = values(stack2); loop { diff --git a/src/Text.mo b/src/Text.mo index 864b7284e..adcf49012 100644 --- a/src/Text.mo +++ b/src/Text.mo @@ -47,6 +47,7 @@ module { /// assert concat == "Hello! 👋"; /// ``` public type Text = Prim.Types.Text; + public type Self = Text; /// Converts the given `Char` to a `Text` value. /// @@ -902,7 +903,7 @@ module { public func compareWith( t1 : Text, t2 : Text, - cmp : (Char, Char) -> Order.Order + cmp : (implicit : (compare : (Char, Char) -> Order.Order)) ) : Order.Order { let cs1 = t1.chars(); let cs2 = t2.chars(); diff --git a/src/Time.mo b/src/Time.mo index 608506de6..2e17dd2db 100644 --- a/src/Time.mo +++ b/src/Time.mo @@ -35,6 +35,7 @@ module { /// Quantity of time expressed in `#days`, `#hours`, `#minutes`, `#seconds`, `#milliseconds`, or `#nanoseconds`. public type Duration = Types.Duration; + public type Self = Duration; /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that: /// diff --git a/src/Timer.mo b/src/Timer.mo index f3ba3bfef..0cf6bd24b 100644 --- a/src/Timer.mo +++ b/src/Timer.mo @@ -31,6 +31,7 @@ import Time "Time"; module { public type TimerId = Nat; + public type Self = TimerId; /// Installs a one-off timer that upon expiration after given duration `d` /// executes the future `job()`. diff --git a/src/Tuples.mo b/src/Tuples.mo index ffbc9876c..3c54ef2fd 100644 --- a/src/Tuples.mo +++ b/src/Tuples.mo @@ -18,6 +18,7 @@ import Types "Types"; module { public module Tuple2 { + public type Self = (A, B); /// Swaps the elements of a tuple. /// /// ```motoko @@ -106,6 +107,7 @@ module { }; public module Tuple3 { + public type Self = (A, B, C); /// Creates a textual representation of a 3-tuple for debugging purposes. /// /// ```motoko @@ -189,6 +191,7 @@ module { }; public module Tuple4 { + public type Self = (A, B, C, D); /// Creates a textual representation of a 4-tuple for debugging purposes. /// /// ```motoko diff --git a/src/VarArray.mo b/src/VarArray.mo index 4b4ac1bc1..9b73000e5 100644 --- a/src/VarArray.mo +++ b/src/VarArray.mo @@ -21,6 +21,7 @@ import Prim "mo:⛔"; module { + public type Self = [var T]; /// Creates an empty mutable array (equivalent to `[var]`). /// /// ```motoko include=import @@ -98,7 +99,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `equal` runs in O(1) time and space. - public func equal(array1 : [var T], array2 : [var T], equal : (T, T) -> Bool) : Bool { + public func equal(array1 : [var T], array2 : [var T], equal : (implicit : (T, T) -> Bool)) : Bool { let size1 = array1.size(); let size2 = array2.size(); if (size1 != size2) { @@ -201,7 +202,7 @@ module { /// /// Space: O(size) /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func sort(array : [var T], compare : (T, T) -> Order.Order) : [var T] { + public func sort(array : [var T], compare : (implicit : (T, T) -> Order.Order)) : [var T] { let newArray = clone(array); sortInPlace(newArray, compare); newArray @@ -221,7 +222,7 @@ module { /// /// Space: O(size) /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func sortInPlace(array : [var T], compare : (T, T) -> Order.Order) : () { + public func sortInPlace(array : [var T], compare : (implicit : (T, T) -> Order.Order)) : () { // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer. let size = array.size(); if (size == 0) { @@ -777,6 +778,19 @@ module { /// Returns whether a mutable array is empty, i.e. contains zero elements. public func isEmpty(array : [var T]) : Bool = array.size() == 0; + /// Transforms an immutable array into a mutable array. + /// + /// ```motoko include=import + /// let array = [0, 1, 2]; + /// let varArray = VarArray.fromArray(array); + /// assert varArray.size() == 3; + /// ``` + /// + /// Runtime: O(size) + /// + /// Space: O(1) + public func fromArray(array : [T]) : [var T] = Prim.Array_tabulateVar(array.size(), func i = array[i]); + /// Converts an iterator to a mutable array. public func fromIter(iter : Types.Iter) : [var T] { var list : Types.Pure.List = null; @@ -944,7 +958,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func indexOf(array : [var T], equal : (T, T) -> Bool, element : T) : ?Nat = nextIndexOf(array, equal, element, 0); + public func indexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = nextIndexOf(array, equal, element, 0); /// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive). /// @@ -962,7 +976,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func nextIndexOf(array : [var T], equal : (T, T) -> Bool, element : T, fromInclusive : Nat) : ?Nat { + public func nextIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T, fromInclusive : Nat) : ?Nat { var index = fromInclusive; let size = array.size(); while (index < size) { @@ -990,7 +1004,7 @@ module { /// Runtime: O(array.size()) /// /// Space: O(1) - public func lastIndexOf(array : [var T], equal : (T, T) -> Bool, element : T) : ?Nat = prevIndexOf(array, equal, element, array.size()); + public func lastIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = prevIndexOf(array, equal, element, array.size()); /// Returns the index of the previous occurence of `element` in the `array` starting from the `from` index (exclusive). /// @@ -1005,7 +1019,7 @@ module { /// /// Runtime: O(array.size()); /// Space: O(1); - public func prevIndexOf(array : [var T], equal : (T, T) -> Bool, element : T, fromExclusive : Nat) : ?Nat { + public func prevIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T, fromExclusive : Nat) : ?Nat { var i = fromExclusive; while (i > 0) { i -= 1; @@ -1155,6 +1169,20 @@ module { Prim.Array_tabulateVar(end - start, func i = array[start + i]) }; + /// Transforms a mutable array into an immutable array. + /// + /// ```motoko include=import + /// let varArray = [var 0, 1, 2]; + /// varArray[2] := 3; + /// let array = VarArray.toArray(varArray); + /// assert array == [0, 1, 3]; + /// ``` + /// + /// Runtime: O(size) + /// + /// Space: O(1) + public func toArray(varArray : [var T]) : [T] = Prim.Array_tabulate(varArray.size(), func i = varArray[i]); + /// Converts the mutable array to its textual representation using `f` to convert each element to `Text`. /// /// ```motoko include=import @@ -1169,7 +1197,7 @@ module { /// Space: O(size) /// /// *Runtime and space assumes that `f` runs in O(1) time and space. - public func toText(array : [var T], f : T -> Text) : Text { + public func toText(array : [var T], f : (implicit : (toText : T -> Text))) : Text { let size = array.size(); if (size == 0) { return "[var]" }; var text = "[var "; @@ -1208,7 +1236,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func compare(array1 : [var T], array2 : [var T], compare : (T, T) -> Order.Order) : Order.Order { + public func compare(array1 : [var T], array2 : [var T], compare : (implicit : (T, T) -> Order.Order)) : Order.Order { let size1 = array1.size(); let size2 = array2.size(); var i = 0; @@ -1244,7 +1272,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `compare` runs in O(1) time and space. - public func binarySearch(array : [var T], compare : (T, T) -> Order.Order, element : T) : { + public func binarySearch(array : [var T], compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat } { diff --git a/src/WeakReference.mo b/src/WeakReference.mo index 2673187ff..eafcb98fc 100644 --- a/src/WeakReference.mo +++ b/src/WeakReference.mo @@ -11,9 +11,10 @@ import Prim "mo:⛔" module { - type WeakReference = { + public type WeakReference = { ref : weak T }; + public type Self = WeakReference; public func allocate(obj : T) : WeakReference { return { ref = Prim.allocWeakRef(obj) } diff --git a/src/pure/List.mo b/src/pure/List.mo index 17a6e764f..1e4a8f2d3 100644 --- a/src/pure/List.mo +++ b/src/pure/List.mo @@ -21,6 +21,7 @@ import Runtime "../Runtime"; module { public type List = Types.Pure.List; + public type Self = List; /// Create an empty list. /// @@ -98,7 +99,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `equal` runs in O(1) time and space. - public func contains(list : List, equal : (T, T) -> Bool, item : T) : Bool = switch list { + public func contains(list : List, equal : (implicit : (T, T) -> Bool), item : T) : Bool = switch list { case (?(h, t)) equal(h, item) or contains(t, equal, item); case _ false }; @@ -656,7 +657,7 @@ module { /// Space: O(size(l1) + size(l2)) /// /// *Runtime and space assumes that `lessThanOrEqual` runs in O(1) time and space. - public func merge(list1 : List, list2 : List, compare : (T, T) -> Order.Order) : List = ( + public func merge(list1 : List, list2 : List, compare : (implicit : (T, T) -> Order.Order)) : List = ( func go(list1 : List, list2 : List, compare : (T, T) -> Order.Order, acc : List) : List = switch (list1, list2) { case ((null, l) or (l, null)) reverse(revAppend(l, acc)); case (?(h1, t1), ?(h2, t2)) switch (compare(h1, h2)) { @@ -685,7 +686,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that `equalItem` runs in O(1) time and space. - public func equal(list1 : List, list2 : List, equalItem : (T, T) -> Bool) : Bool = switch (list1, list2) { + public func equal(list1 : List, list2 : List, equalItem : (implicit : (equal : (T, T) -> Bool))) : Bool = switch (list1, list2) { case (null, null) true; case (?(h1, t1), ?(h2, t2)) equalItem(h1, h2) and equal(t1, t2, equalItem); case _ false @@ -710,7 +711,7 @@ module { /// Space: O(1) /// /// *Runtime and space assumes that argument `compare` runs in O(1) time and space. - public func compare(list1 : List, list2 : List, compareItem : (T, T) -> Order.Order) : Order.Order = switch (list1, list2) { + public func compare(list1 : List, list2 : List, compareItem : (implicit : (compare : (T, T) -> Order.Order))) : Order.Order = switch (list1, list2) { case (?(h1, t1), ?(h2, t2)) switch (compareItem(h1, h2)) { case (#equal) compare(t1, t2, compareItem); case o o @@ -1067,7 +1068,7 @@ module { /// Runtime: O(size) /// /// Space: O(size) - public func toText(list : List, f : T -> Text) : Text { + public func toText(list : List, f : (implicit : T -> Text)) : Text { var text = "PureList["; var first = true; forEach( diff --git a/src/pure/Map.mo b/src/pure/Map.mo index b73d1c236..73b4868df 100644 --- a/src/pure/Map.mo +++ b/src/pure/Map.mo @@ -61,6 +61,7 @@ import Runtime "../Runtime"; module { public type Map = Types.Pure.Map; + public type Self = Map; type Tree = Types.Pure.Map.Tree; @@ -140,7 +141,7 @@ module { /// Space: `O(1)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func containsKey(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool = Internal.contains(map.root, compare, key); + public func containsKey(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool = Internal.contains(map.root, compare, key); /// Given, `map` ordered by `compare`, return the value associated with key `key` if present and `null` otherwise. /// @@ -161,7 +162,7 @@ module { /// Space: `O(1)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func get(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V = Internal.get(map.root, compare, key); + public func get(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V = Internal.get(map.root, compare, key); /// Given `map` ordered by `compare`, insert a mapping from `key` to `value`. /// Returns the modified map and `true` if the key is new to map, otherwise `false`. @@ -194,7 +195,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `m := Map.add(m, cmp, k, v)`) /// causes collecting `O(log(n))` nodes. - public func insert(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, Bool) { + public func insert(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, Bool) { switch (swap(map, compare, key, value)) { case (map1, null) (map1, true); case (map1, _) (map1, false) @@ -230,7 +231,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `m := Map.add(m, cmp, k, v)`) /// causes collecting `O(log(n))` nodes. - public func add(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : Map { + public func add(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : Map { swap(map, compare, key, value).0 }; @@ -267,7 +268,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `m := Map.swap(m, Nat.compare, k, v).0`) /// causes collecting `O(log(n))` nodes. - public func swap(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, ?V) { + public func swap(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, ?V) { switch (Internal.swap(map.root, compare, key, value)) { case (t, null) { ({ root = t; size = map.size + 1 }, null) }; case (t, v) { ({ root = t; size = map.size }, v) } @@ -301,7 +302,7 @@ module { /// Space: `O(log(n))`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func replace(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, ?V) { + public func replace(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, ?V) { // TODO: Could be optimized in future if (containsKey(map, compare, key)) { swap(map, compare, key, value) @@ -337,7 +338,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `map := Map.delete(map, compare, k).0`) /// causes collecting `O(log(n))` nodes. - public func remove(map : Map, compare : (K, K) -> Order.Order, key : K) : Map { + public func remove(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Map { switch (Internal.remove(map.root, compare, key)) { case (_, null) map; case (t, ?_) { { root = t; size = map.size - 1 } } @@ -377,7 +378,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `map := Map.delete(map, compare, k).0`) /// causes collecting `O(log(n))` nodes. - public func delete(map : Map, compare : (K, K) -> Order.Order, key : K) : (Map, Bool) { + public func delete(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : (Map, Bool) { switch (Internal.remove(map.root, compare, key)) { case (_, null) { (map, false) }; case (t, ?_) { ({ root = t; size = map.size - 1 }, true) } @@ -416,7 +417,7 @@ module { /// Note: The returned map shares with the `m` most of the tree nodes. /// Garbage collecting one of maps (e.g. after an assignment `map := Map.remove(map, compare, key)`) /// causes collecting `O(log(n))` nodes. - public func take(map : Map, compare : (K, K) -> Order.Order, key : K) : (Map, ?V) { + public func take(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : (Map, ?V) { switch (Internal.remove(map.root, compare, key)) { case (t, null) { ({ root = t; size = map.size }, null) }; case (t, v) { ({ root = t; size = map.size - 1 }, v) } @@ -594,7 +595,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func fromIter(iter : Iter.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map = Internal.fromIter(iter, compare); + public func fromIter(iter : Iter.Iter<(K, V)>, compare : (implicit : (K, K) -> Order.Order)) : Map = Internal.fromIter(iter, compare); /// Given a `map` and function `f`, creates a new map by applying `f` to each entry in the map `m`. Each entry /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where @@ -798,7 +799,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of key-value entries stored in the map and /// assuming that the `compare` function implements an `O(1)` comparison. - public func filter(map : Map, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map = Internal.filter(map, compare, criterion); + public func filter(map : Map, compare : (implicit : (K, K) -> Order.Order), criterion : (K, V) -> Bool) : Map = Internal.filter(map, compare, criterion); /// Given a `map`, comparison `compare` and function `f`, /// constructs a new map ordered by `compare`, by applying `f` to each entry in `map`. @@ -832,11 +833,11 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func filterMap(map : Map, compare : (K, K) -> Order.Order, f : (K, V1) -> ?V2) : Map = Internal.mapFilter(map, compare : (K, K) -> Order.Order, f); + public func filterMap(map : Map, compare : (implicit : (K, K) -> Order.Order), f : (K, V1) -> ?V2) : Map = Internal.mapFilter(map, compare : (K, K) -> Order.Order, f); /// Validate the representation invariants of the given `map`. /// Assert if any invariants are violated. - public func assertValid(map : Map, compare : (K, K) -> Order.Order) : () = Internal.validate(map, compare); + public func assertValid(map : Map, compare : (implicit : (K, K) -> Order.Order)) : () = Internal.validate(map, compare); /// Converts the `map` to its textual representation using `keyFormat` and `valueFormat` to convert each key and value to `Text`. /// @@ -855,7 +856,7 @@ module { /// Space: O(size) /// /// *Runtime and space assumes that `keyFormat` and `valueFormat` run in O(1) time and space. - public func toText(map : Map, keyFormat : K -> Text, valueFormat : V -> Text) : Text { + public func toText(map : Map, keyFormat : (implicit : (toText : K -> Text)), valueFormat : (implicit : (toText : V -> Text))) : Text { var text = "PureMap{"; var sep = ""; for ((k, v) in entries(map)) { @@ -883,7 +884,7 @@ module { /// /// Runtime: `O(n)`. /// Space: `O(1)`. - public func equal(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, equalValue : (V, V) -> Bool) : Bool { + public func equal(map1 : Map, map2 : Map, compare : (implicit : (K, K) -> Order.Order), equal : (implicit : (V, V) -> Bool)) : Bool { if (map1.size != map2.size) { return false }; @@ -897,7 +898,7 @@ module { return true }; case (?(key1, value1), ?(key2, value2)) { - if (not (compareKey(key1, key2) == #equal) or not equalValue(value1, value2)) { + if (not (compare(key1, key2) == #equal) or not equal(value1, value2)) { return false } }; @@ -946,7 +947,7 @@ module { /// assuming that `compareKey` and `compareValue` have runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func compare(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order { + public func compare(map1 : Map, map2 : Map, compareKey : (implicit : (compare : (K, K) -> Order.Order)), compareValue : (implicit : (compare : (V, V) -> Order.Order))) : Order.Order { let iterator1 = entries(map1); let iterator2 = entries(map2); loop { diff --git a/src/pure/Queue.mo b/src/pure/Queue.mo index 0392bfabd..64bd5b96c 100644 --- a/src/pure/Queue.mo +++ b/src/pure/Queue.mo @@ -40,6 +40,7 @@ module { /// Double-ended queue data type. public type Queue = Types.Pure.Queue; + public type Self = Queue; /// Create a new empty queue. /// @@ -124,7 +125,7 @@ module { /// Runtime: `O(size)` /// /// Space: `O(1)` - public func contains(queue : Queue, equal : (T, T) -> Bool, item : T) : Bool = List.contains(queue.0, equal, item) or List.contains(queue.2, equal, item); + public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), item : T) : Bool = List.contains(queue.0, equal, item) or List.contains(queue.2, equal, item); /// Inspect the optional element on the front end of a queue. /// Returns `null` if `queue` is empty. Otherwise, the front element of `queue`. @@ -400,7 +401,7 @@ module { /// Runtime: O(size) /// /// Space: O(size) - public func equal(queue1 : Queue, queue2 : Queue, equal : (T, T) -> Bool) : Bool { + public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool { if (queue1.1 != queue2.1) { return false }; @@ -578,7 +579,7 @@ module { /// Runtime: `O(size)` /// /// Space: `O(size)` - public func toText(queue : Queue, f : T -> Text) : Text { + public func toText(queue : Queue, f : (implicit : (toText : T -> Text))) : Text { var text = "PureQueue["; func add(item : T) { if (text.size() > 10) text #= ", "; @@ -607,7 +608,7 @@ module { /// Space: `O(size)` /// /// *Runtime and space assumes that argument `compareItem` runs in `O(1)` time and space. - public func compare(queue1 : Queue, queue2 : Queue, compareItem : (T, T) -> Order.Order) : Order.Order { + public func compare(queue1 : Queue, queue2 : Queue, compareItem : (implicit : (compare : (T, T) -> Order.Order))) : Order.Order { let (i1, i2) = (values queue1, values queue2); loop switch (i1.next(), i2.next()) { case (?v1, ?v2) switch (compareItem(v1, v2)) { diff --git a/src/pure/RealTimeQueue.mo b/src/pure/RealTimeQueue.mo index b6ea2e796..60af46ac6 100644 --- a/src/pure/RealTimeQueue.mo +++ b/src/pure/RealTimeQueue.mo @@ -62,6 +62,7 @@ module { #idles : (Idle, Idle); #rebal : States }; + public type Self = Queue; /// Create a new empty queue. /// @@ -157,17 +158,17 @@ module { /// Runtime: `O(size)` /// /// Space: `O(1)` - public func contains(queue : Queue, eq : (T, T) -> Bool, item : T) : Bool = switch queue { + public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), item : T) : Bool = switch queue { case (#empty) false; - case (#one(x)) eq(x, item); - case (#two(x, y)) eq(x, item) or eq(y, item); - case (#three(x, y, z)) eq(x, item) or eq(y, item) or eq(z, item); - case (#idles(((l1, l2), _), ((r1, r2), _))) List.contains(l1, eq, item) or List.contains(l2, eq, item) or List.contains(r2, eq, item) or List.contains(r1, eq, item); // note that the order of the right stack is reversed, but for this operation it does not matter + case (#one(x)) equal(x, item); + case (#two(x, y)) equal(x, item) or equal(y, item); + case (#three(x, y, z)) equal(x, item) or equal(y, item) or equal(z, item); + case (#idles(((l1, l2), _), ((r1, r2), _))) List.contains(l1, equal, item) or List.contains(l2, equal, item) or List.contains(r2, equal, item) or List.contains(r1, equal, item); // note that the order of the right stack is reversed, but for this operation it does not matter case (#rebal(_, big, small)) { let (extraB, _, (oldB1, oldB2), _) = BigState.current(big); let (extraS, _, (oldS1, oldS2), _) = SmallState.current(small); // note that the order of one of the stacks is reversed (depending on the `direction` field), but for this operation it does not matter - List.contains(extraB, eq, item) or List.contains(oldB1, eq, item) or List.contains(oldB2, eq, item) or List.contains(extraS, eq, item) or List.contains(oldS1, eq, item) or List.contains(oldS2, eq, item) + List.contains(extraB, equal, item) or List.contains(oldB1, equal, item) or List.contains(oldB2, equal, item) or List.contains(extraS, equal, item) or List.contains(oldS1, equal, item) or List.contains(oldS2, equal, item) } }; @@ -595,16 +596,16 @@ module { /// Runtime: `O(size)` /// /// Space: `O(size)` - public func equal(queue1 : Queue, queue2 : Queue, equality : (T, T) -> Bool) : Bool { + public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool { if (size(queue1) != size(queue2)) { return false }; - func go(queue1 : Queue, queue2 : Queue, equality : (T, T) -> Bool) : Bool = switch (popFront queue1, popFront queue2) { + func go(queue1 : Queue, queue2 : Queue, equal : (T, T) -> Bool) : Bool = switch (popFront queue1, popFront queue2) { case (null, null) true; - case (?(x1, tail1), ?(x2, tail2)) equality(x1, x2) and go(tail1, tail2, equality); // Note that this is tail recursive (`and` is expanded to `if`). + case (?(x1, tail1), ?(x2, tail2)) equal(x1, x2) and go(tail1, tail2, equal); // Note that this is tail recursive (`and` is expanded to `if`). case _ false }; - go(queue1, queue2, equality) + go(queue1, queue2, equal) }; /// Compare two queues lexicographically using a provided comparison function to compare their elements. @@ -624,13 +625,13 @@ module { /// Runtime: `O(size)` /// /// Space: `O(size)` - public func compare(queue1 : Queue, queue2 : Queue, comparison : (T, T) -> Types.Order) : Types.Order = switch (popFront queue1, popFront queue2) { + public func compare(queue1 : Queue, queue2 : Queue, compareItem : (implicit : (compare : (T, T) -> Types.Order))) : Types.Order = switch (popFront queue1, popFront queue2) { case (null, null) #equal; case (null, _) #less; case (_, null) #greater; case (?(x1, queue1Tail), ?(x2, queue2Tail)) { - switch (comparison(x1, x2)) { - case (#equal) compare(queue1Tail, queue2Tail, comparison); + switch (compareItem(x1, x2)) { + case (#equal) compare(queue1Tail, queue2Tail, compareItem); case order order } } @@ -828,7 +829,7 @@ module { /// Space: `O(size)` /// /// *Runtime and space assumes that f runs in `O(1)` time and space. - public func toText(queue : Queue, f : T -> Text) : Text { + public func toText(queue : Queue, f : (implicit : (toText : T -> Text))) : Text { var text = "RealTimeQueue["; var first = true; for (t in values queue) { diff --git a/src/pure/Set.mo b/src/pure/Set.mo index 2823efbab..a2c8f510e 100644 --- a/src/pure/Set.mo +++ b/src/pure/Set.mo @@ -47,6 +47,7 @@ module { /// To ensure that property the `Set` does not have any methods, /// instead they are gathered in the functor-like class `Operations` (see example there). public type Set = Types.Pure.Set; + public type Self = Set; /// Red-black tree of nodes with ordered set elements. /// Leaves are considered implicitly black. @@ -74,7 +75,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func fromIter(iter : Iter.Iter, compare : (T, T) -> Order.Order) : Set { + public func fromIter(iter : Iter.Iter, compare : (implicit : (T, T) -> Order.Order)) : Set { var set = empty() : Set; for (val in iter) { set := Internal.add(set, compare, val) @@ -113,7 +114,7 @@ module { /// Note: The returned set shares with the `set` most of the tree nodes. /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.add(m, c, e)`) /// causes collecting `O(log(n))` nodes. - public func add(set : Set, compare : (T, T) -> Order.Order, elem : T) : Set = Internal.add(set, compare, elem); + public func add(set : Set, compare : (implicit : (T, T) -> Order.Order), elem : T) : Set = Internal.add(set, compare, elem); /// Given `set` ordered by `compare`, insert the new `element`, /// returning the set extended with `element` and a Boolean indicating @@ -147,7 +148,7 @@ module { /// Note: The returned set shares with the `set` most of the tree nodes. /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.add(m, c, e)`) /// causes collecting `O(log(n))` nodes. - public func insert(set : Set, compare : (T, T) -> Order.Order, elem : T) : (Set, Bool) = Internal.insert(set, compare, elem); + public func insert(set : Set, compare : (implicit : (T, T) -> Order.Order), elem : T) : (Set, Bool) = Internal.insert(set, compare, elem); /// Given `set` ordered by `compare` return the set with `element` removed. /// Return the set unchanged if the element was absent. @@ -175,7 +176,7 @@ module { /// Note: The returned set shares with `set` most of the tree nodes. /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.delete(m, c, e)`) /// causes collecting `O(log(n))` nodes. - public func remove(set : Set, compare : (T, T) -> Order.Order, element : T) : Set = Internal.remove(set, compare, element); + public func remove(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Set = Internal.remove(set, compare, element); /// Given `set` ordered by `compare`, delete `element` from the set, returning /// either the set without the element and a Boolean indicating whether @@ -208,7 +209,7 @@ module { /// Note: The returned set shares with `set` most of the tree nodes. /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.delete(m, c, e)`) /// causes collecting `O(log(n))` nodes. - public func delete(set : Set, compare : (T, T) -> Order.Order, element : T) : (Set, Bool) = Internal.delete(set, compare, element); + public func delete(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : (Set, Bool) = Internal.delete(set, compare, element); /// Tests whether the set contains the provided element. /// @@ -230,7 +231,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func contains(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool = Internal.contains(set.root, compare, element); + public func contains(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool = Internal.contains(set.root, compare, element); /// Get the maximal element of the set `set` if it is not empty, otherwise returns `null` /// @@ -298,7 +299,7 @@ module { /// and assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage. - public func union(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func union(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { if (size(set1) < size(set2)) { foldLeft(set1, set2, func(acc : Set, elem : T) : Set { Internal.add(acc, compare, elem) }) } else { @@ -329,7 +330,7 @@ module { /// and assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(m)` temporary objects that will be collected as garbage. - public func intersection(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func intersection(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { let elems = List.empty(); if (set1.size < set2.size) { Internal.iterate( @@ -376,7 +377,7 @@ module { /// and assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage. - public func difference(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set { + public func difference(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set { if (size(set1) < size(set2)) { let elems = List.empty(); /* imperative! */ Internal.iterate( @@ -427,7 +428,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func map(s : Set, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set = Internal.foldLeft(s.root, empty(), func(acc : Set, elem : T1) : Set { Internal.add(acc, compare, project(elem)) }); + public func map(s : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> T2) : Set = Internal.foldLeft(s.root, empty(), func(acc : Set, elem : T1) : Set { Internal.add(acc, compare, project(elem)) }); /// Apply an operation on each element contained in the set. /// The operation is applied in ascending order of the elements. @@ -480,7 +481,7 @@ module { /// Space: `O(n)`. /// where `n` denotes the number of elements stored in the set and /// assuming that the `compare` function implements an `O(1)` comparison. - public func filter(set : Set, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set { + public func filter(set : Set, compare : (implicit : (T, T) -> Order.Order), criterion : T -> Bool) : Set { foldLeft>( set, empty(), @@ -527,7 +528,7 @@ module { /// assuming that the `compare` function implements an `O(1)` comparison. /// /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage. - public func filterMap(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set { + public func filterMap(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> ?T2) : Set { func combine(acc : Set, elem : T1) : Set { switch (project(elem)) { case null { acc }; @@ -560,7 +561,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func isSubset(s1 : Set, s2 : Set, compare : (T, T) -> Order.Order) : Bool { + public func isSubset(s1 : Set, s2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool { if (s1.size > s2.size) { return false }; isSubsetHelper(s1.root, s2.root, compare) }; @@ -586,7 +587,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func equal(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Bool { + public func equal(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool { if (set1.size != set2.size) { return false }; isSubsetHelper(set1.root, set2.root, compare) }; @@ -649,7 +650,7 @@ module { /// assuming that `compare` has runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func compare(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Order.Order { + public func compare(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Order.Order { // TODO: optimize using recursion on set1? let iterator1 = values(set1); let iterator2 = values(set2); @@ -915,7 +916,7 @@ module { /// Test helper that check internal invariant for the given set `s`. /// Raise an error (for a stack trace) if invariants are violated. - public func assertValid(set : Set, compare : (T, T) -> Order.Order) : () { + public func assertValid(set : Set, compare : (implicit : (T, T) -> Order.Order)) : () { Internal.assertValid(set, compare) }; @@ -942,7 +943,7 @@ module { /// assuming that `elementFormat` has runtime and space costs of `O(1)`. /// /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage. - public func toText(set : Set, elementFormat : T -> Text) : Text { + public func toText(set : Set, elementFormat : (implicit : (toText : T -> Text))) : Text { var text = "PureSet{"; var sep = ""; for (element in values(set)) { @@ -984,7 +985,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `n` denotes the number of elements stored in all the sub-sets, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func flatten(setOfSets : Set>, compare : (T, T) -> Order.Order) : Set { + public func flatten(setOfSets : Set>, compare : (implicit : (T, T) -> Order.Order)) : Set { var result = empty(); for (set in values(setOfSets)) { result := union(result, set, compare) @@ -1018,7 +1019,7 @@ module { /// Space: `O(1)` retained memory plus garbage, see the note below. /// where `n` denotes the number of elements stored in the iterated sets, /// and assuming that the `compare` function implements an `O(1)` comparison. - public func join(setIterator : Iter.Iter>, compare : (T, T) -> Order.Order) : Set { + public func join(setIterator : Iter.Iter>, compare : (implicit : (T, T) -> Order.Order)) : Set { var result = empty(); for (set in setIterator) { result := union(result, set, compare) diff --git a/test/List.test.mo b/test/List.test.mo index 867077f83..c26cb98d6 100644 --- a/test/List.test.mo +++ b/test/List.test.mo @@ -27,10 +27,10 @@ var list = List.empty(); let sizes = List.empty(); for (i in Nat.rangeInclusive(0, n)) { - List.add(sizes, List.size(list)); - List.add(list, i) + sizes.add(list.size()); + list.add(i) }; -List.add(sizes, List.size(list)); +sizes.add(list.size()); class OrderTestable(initItem : Order.Order) : T.TestableItem { public let item = initItem; @@ -56,8 +56,8 @@ run( [ test( "clone", - List.toArray(List.clone(list)), - M.equals(T.array(T.natTestable, List.toArray(list))) + list.clone().toArray(), + M.equals(T.array(T.natTestable, list.toArray())) ) ] ) @@ -69,34 +69,34 @@ run( [ test( "sizes", - List.toArray(sizes), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n + 1)))) + sizes.toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n + 1).toArray())) ), test( "elements", - List.toArray(list), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ) ] ) ); -assert List.find(list, func(a : Nat) : Bool = a == 123456) == null; -assert List.find(list, func(a : Nat) : Bool = a == 0) == ?0; +assert list.find(func(a : Nat) : Bool = a == 123456) == null; +assert list.find(func(a : Nat) : Bool = a == 0) == ?0; -assert List.indexOf(list, Nat.equal, n + 1) == null; -assert List.findIndex(list, func(a : Nat) : Bool = a == n + 1) == null; -assert List.indexOf(list, Nat.equal, n) == ?n; -assert List.findIndex(list, func(a : Nat) : Bool = a == n) == ?n; +assert list.indexOf(Nat.equal, n + 1) == null; +assert list.findIndex(func(a : Nat) : Bool = a == n + 1) == null; +assert list.indexOf(Nat.equal, n) == ?n; +assert list.findIndex(func(a : Nat) : Bool = a == n) == ?n; -assert List.lastIndexOf(list, Nat.equal, n + 1) == null; -assert List.findLastIndex(list, func(a : Nat) : Bool = a == n + 1) == null; +assert list.lastIndexOf(Nat.equal, n + 1) == null; +assert list.findLastIndex(func(a : Nat) : Bool = a == n + 1) == null; -assert List.lastIndexOf(list, Nat.equal, 0) == ?0; -assert List.findLastIndex(list, func(a : Nat) : Bool = a == 0) == ?0; +assert list.lastIndexOf(Nat.equal, 0) == ?0; +assert list.findLastIndex(func(a : Nat) : Bool = a == 0) == ?0; -assert List.all(list, func(x : Nat) : Bool = 0 <= x and x <= n); -assert List.any(list, func(x : Nat) : Bool = x == n / 2); +assert list.all(func(x : Nat) : Bool = 0 <= x and x <= n); +assert list.any(func(x : Nat) : Bool = x == n / 2); run( suite( @@ -104,38 +104,38 @@ run( [ test( "values", - Iter.toArray(List.values(list)), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.values().toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ), test( "reverseValues", - Iter.toArray(List.reverseValues(list)), - M.equals(T.array(T.natTestable, Iter.toArray(Iter.reverse(Nat.rangeInclusive(0, n))))) + list.reverseValues().toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).reverse().toArray())) ), test( "keys", - Iter.toArray(List.keys(list)), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.keys().toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ), test( "enumerate1", - Iter.toArray(Iter.map<(Nat, Nat), Nat>(List.enumerate(list), func((a, b)) { b })), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.enumerate().map(func((a, b)) { b }).toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ), test( "enumerate2", - Iter.toArray(Iter.map<(Nat, Nat), Nat>(List.enumerate(list), func((a, b)) { a })), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.enumerate().map(func((a, b)) { a }).toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ), test( "reverseEnumerate1", - Iter.toArray(Iter.map<(Nat, Nat), Nat>(List.reverseEnumerate(list), func((a, b)) { b })), - M.equals(T.array(T.natTestable, Iter.toArray(Iter.reverse(Nat.rangeInclusive(0, n))))) + list.reverseEnumerate().map(func((a, b)) { b }).toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).reverse().toArray())) ), test( "reverseEnumerate2", - Iter.toArray(Iter.map<(Nat, Nat), Nat>(List.reverseEnumerate(list), func((a, b)) { a })), - M.equals(T.array(T.natTestable, Iter.toArray(Iter.reverse(Nat.rangeInclusive(0, n))))) + list.reverseEnumerate().map(func((a, b)) { a }).toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).reverse().toArray())) ) ] ) @@ -153,27 +153,27 @@ run( [ test( "init with toArray", - List.toArray(List.repeat(0, n)), + List.repeat(0, n).toArray(), M.equals(T.array(T.natTestable, Array.tabulate(n, func(_) = 0))) ), test( "init with values", - Iter.toArray(List.values(List.repeat(0, n))), + List.repeat(0, n).values().toArray(), M.equals(T.array(T.natTestable, Array.tabulate(n, func(_) = 0))) ), test( "add many with toArray", - List.toArray(for_add_many), + for_add_many.toArray(), M.equals(T.array(T.natTestable, Array.tabulate(2 * n, func(_) = 0))) ), test( "add many with vals", - Iter.toArray(List.values(for_add_many)), + Iter.toArray(for_add_many.values()), M.equals(T.array(T.natTestable, Array.tabulate(2 * n, func(_) = 0))) ), test( "addFromIter", - List.toArray(for_add_iter), + for_add_iter.toArray(), M.equals(T.array(T.natTestable, Array.tabulate(2 * n, func(_) = 0))) ) ] @@ -190,13 +190,13 @@ run( [ test( "size", - List.size(list), + list.size(), M.equals(T.nat(n + 1)) ), test( "elements", - List.toArray(list), - M.equals(T.array(T.natTestable, Iter.toArray(Iter.reverse(Nat.rangeInclusive(0, n))))) + list.toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).reverse().toArray())) ) ] ) @@ -204,12 +204,12 @@ run( let removed = List.empty(); for (i in Nat.rangeInclusive(0, n)) { - List.add(removed, unwrap(List.removeLast(list))) + removed.add(unwrap(list.removeLast())) }; let empty = List.empty(); let emptied = List.singleton(0); -let _ = List.removeLast(emptied); +let _ = emptied.removeLast(); run( suite( @@ -217,13 +217,13 @@ run( [ test( "size", - List.size(list), + list.size(), M.equals(T.nat(0)) ), test( "elements", - List.toArray(removed), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + removed.toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ), test( "empty", @@ -240,13 +240,13 @@ run( ); // Test last and first -assert List.last(list) == null; -assert List.first(list) == null; +assert list.first() == null; +assert list.last() == null; for (i in Nat.rangeInclusive(0, n)) { - List.add(list, i); - assert List.last(list) == ?i; - assert List.first(list) == ?0 + list.add(i); + assert list.last() == ?i; + assert list.first() == ?0 }; run( @@ -255,8 +255,8 @@ run( [ test( "elements", - List.toArray(list), - M.equals(T.array(T.natTestable, Iter.toArray(Nat.rangeInclusive(0, n)))) + list.toArray(), + M.equals(T.array(T.natTestable, Nat.rangeInclusive(0, n).toArray())) ) ] ) @@ -268,42 +268,42 @@ run( [ test( "first", - List.first(list), + list.first(), M.equals(T.optional(T.natTestable, ?0)) ), test( "first empty", - List.first(empty), + empty.first(), M.equals(T.optional(T.natTestable, null : ?Nat)) ), test( "first emptied", - List.first(emptied), + emptied.first(), M.equals(T.optional(T.natTestable, null : ?Nat)) ), test( "last of len N", - List.last(list), + list.last(), M.equals(T.optional(T.natTestable, ?n)) ), test( "last of len 1", - List.last(List.repeat(1, 1)), + List.repeat(1, 1).last(), M.equals(T.optional(T.natTestable, ?1)) ), test( "last of 6", - List.last(List.fromArray([0, 1, 2, 3, 4, 5])), + List.fromArray([0, 1, 2, 3, 4, 5]).last(), M.equals(T.optional(T.natTestable, ?5)) ), test( "last empty", - List.last(List.empty()), + List.empty().last(), M.equals(T.optional(T.natTestable, null : ?Nat)) ), test( "last emptied", - List.last(emptied), + emptied.last(), M.equals(T.optional(T.natTestable, null : ?Nat)) ) ] @@ -333,13 +333,13 @@ Test.suite( ); var sumN = 0; -List.forEach(list, func(i) { sumN += i }); +list.forEach(func(i) { sumN += i }); var sumRev = 0; -List.reverseForEach(list, func(i) { sumRev += i }); +list.reverseForEach(func(i) { sumRev += i }); var sum1 = 0; -List.forEach(List.repeat(1, 1), func(i) { sum1 += i }); +List.repeat(1, 1).forEach(func(i) { sum1 += i }); var sum0 = 0; -List.forEach(List.empty(), func(i) { sum0 += i }); +List.empty().forEach(func(i) { sum0 += i }); run( suite( @@ -372,9 +372,9 @@ run( /* --------------------------------------- */ var sumItems = 0; -List.forEachEntry(list, func(i, x) { sumItems += i + x }); +list.forEachEntry(func(i, x) { sumItems += i + x }); var sumItemsRev = 0; -List.forEachEntry(list, func(i, x) { sumItemsRev += i + x }); +list.forEachEntry(func(i, x) { sumItemsRev += i + x }); run( suite( @@ -404,12 +404,12 @@ run( [ test( "true", - List.contains(list, Nat.equal, 2), + list.contains(Nat.equal, 2), M.equals(T.bool(true)) ), test( "true", - List.contains(list, Nat.equal, 9), + list.contains(Nat.equal, 9), M.equals(T.bool(false)) ) ] @@ -426,12 +426,12 @@ run( [ test( "true", - List.contains(list, Nat.equal, 2), + list.contains(Nat.equal, 2), M.equals(T.bool(false)) ), test( "true", - List.contains(list, Nat.equal, 9), + list.contains(Nat.equal, 9), M.equals(T.bool(false)) ) ] @@ -448,7 +448,7 @@ run( [ test( "return value", - List.max(list, Nat.compare), + list.max(Nat.compare), M.equals(T.optional(T.natTestable, ?10)) ) ] @@ -465,7 +465,7 @@ run( [ test( "return value", - List.min(list, Nat.compare), + list.min(Nat.compare), M.equals(T.optional(T.natTestable, ?0)) ) ] @@ -484,22 +484,22 @@ run( [ test( "empty lists", - List.equal(List.empty(), List.empty(), Nat.equal), + List.empty().equal(List.empty(), Nat.equal), M.equals(T.bool(true)) ), test( "non-empty lists", - List.equal(list, List.clone(list), Nat.equal), + list.equal(List.clone(list), Nat.equal), M.equals(T.bool(true)) ), test( "non-empty and empty lists", - List.equal(list, List.empty(), Nat.equal), + list.equal(List.empty(), Nat.equal), M.equals(T.bool(false)) ), test( "non-empty lists mismatching lengths", - List.equal(list, list2, Nat.equal), + list.equal(list2, Nat.equal), M.equals(T.bool(false)) ) ] @@ -519,27 +519,27 @@ run( [ test( "empty lists", - List.compare(List.empty(), List.empty(), Nat.compare), + List.empty().compare(List.empty(), Nat.compare), M.equals(OrderTestable(#equal)) ), test( "non-empty lists equal", - List.compare(list, List.clone(list), Nat.compare), + list.compare(List.clone(list), Nat.compare), M.equals(OrderTestable(#equal)) ), test( "non-empty and empty lists", - List.compare(list, List.empty(), Nat.compare), + list.compare(List.empty(), Nat.compare), M.equals(OrderTestable(#greater)) ), test( "non-empty lists mismatching lengths", - List.compare(list, list2, Nat.compare), + list.compare(list2, Nat.compare), M.equals(OrderTestable(#greater)) ), test( "non-empty lists lexicographic difference", - List.compare(list, list3, Nat.compare), + list.compare(list3, Nat.compare), M.equals(OrderTestable(#less)) ) ] @@ -556,17 +556,17 @@ run( [ test( "empty list", - List.toText(List.empty(), Nat.toText), + List.empty().toText(Nat.toText), M.equals(T.text("List[]")) ), test( "singleton list", - List.toText(List.singleton(3), Nat.toText), + List.singleton(3).toText(Nat.toText), M.equals(T.text("List[3]")) ), test( "non-empty list", - List.toText(list, Nat.toText), + list.toText(Nat.toText), M.equals(T.text("List[0, 1, 2, 3, 4, 5]")) ) ] @@ -581,10 +581,10 @@ list3 := List.empty(); var list4 = List.singleton(3); -List.reverseInPlace(list); -List.reverseInPlace(list2); -List.reverseInPlace(list3); -List.reverseInPlace(list4); +list.reverseInPlace(); +list2.reverseInPlace(); +list3.reverseInPlace(); +list4.reverseInPlace(); run( suite( @@ -592,22 +592,22 @@ run( [ test( "even elements", - List.toArray(list), + list.toArray(), M.equals(T.array(T.natTestable, [7, 6, 5, 4, 3, 2, 1, 0])) ), test( "odd elements", - List.toArray(list2), + list2.toArray(), M.equals(T.array(T.natTestable, [6, 5, 4, 3, 2, 1, 0])) ), test( "empty", - List.toArray(list3), + list3.toArray(), M.equals(T.array(T.natTestable, [] : [Nat])) ), test( "singleton", - List.toArray(list4), + list4.toArray(), M.equals(T.array(T.natTestable, [3])) ) ] @@ -616,10 +616,10 @@ run( /* --------------------------------------- */ -list := List.reverse(List.fromArray([0, 1, 2, 3, 4, 5, 6, 7])); -list2 := List.reverse(List.fromArray([0, 1, 2, 3, 4, 5, 6])); -list3 := List.reverse(List.empty()); -list4 := List.reverse(List.singleton(3)); +list := List.fromArray([0, 1, 2, 3, 4, 5, 6, 7]).reverse(); +list2 := List.fromArray([0, 1, 2, 3, 4, 5, 6]).reverse(); +list3 := List.empty().reverse(); +list4 := List.singleton(3).reverse(); run( suite( @@ -627,22 +627,22 @@ run( [ test( "even elements", - List.toArray(list), + list.toArray(), M.equals(T.array(T.natTestable, [7, 6, 5, 4, 3, 2, 1, 0])) ), test( "odd elements", - List.toArray(list2), + list2.toArray(), M.equals(T.array(T.natTestable, [6, 5, 4, 3, 2, 1, 0])) ), test( "empty", - List.toArray(list3), + list3.toArray(), M.equals(T.array(T.natTestable, [] : [Nat])) ), test( "singleton", - List.toArray(list4), + list4.toArray(), M.equals(T.array(T.natTestable, [3])) ) ] @@ -659,12 +659,12 @@ run( [ test( "return value", - List.foldLeft(list, "", func(acc, x) = acc # Nat.toText(x)), + list.foldLeft("", func(acc, x) = acc # Nat.toText(x)), M.equals(T.text("0123456")) ), test( "return value empty", - List.foldLeft(List.empty(), "", func(acc, x) = acc # Nat.toText(x)), + List.empty().foldLeft("", func(acc, x) = acc # Nat.toText(x)), M.equals(T.text("")) ) ] @@ -681,12 +681,12 @@ run( [ test( "return value", - List.foldRight(list, "", func(x, acc) = acc # Nat.toText(x)), + list.foldRight("", func(x, acc) = acc # Nat.toText(x)), M.equals(T.text("6543210")) ), test( "return value empty", - List.foldRight(List.empty(), "", func(x, acc) = acc # Nat.toText(x)), + List.empty().foldRight("", func(x, acc) = acc # Nat.toText(x)), M.equals(T.text("")) ) ] @@ -703,12 +703,12 @@ run( [ test( "true", - List.isEmpty(List.empty()), + List.empty().isEmpty(), M.equals(T.bool(true)) ), test( "false", - List.isEmpty(list), + list.isEmpty(), M.equals(T.bool(false)) ) ] @@ -725,12 +725,12 @@ run( [ test( "map", - List.toArray(List.map(list, Nat.toText)), + list.map(Nat.toText).toArray(), M.equals(T.array(T.textTestable, ["0", "1", "2", "3", "4", "5", "6"])) ), test( "empty", - List.isEmpty(List.map(List.empty(), Nat.toText)), + List.empty().map(Nat.toText).isEmpty(), M.equals(T.bool(true)) ) ] @@ -747,22 +747,22 @@ run( [ test( "filter evens", - List.toArray(List.filter(list, func x = x % 2 == 0)), + list.filter(func x = x % 2 == 0).toArray(), M.equals(T.array(T.natTestable, [0, 2, 4, 6])) ), test( "filter none", - List.toArray(List.filter(list, func _ = false)), + list.filter(func _ = false).toArray(), M.equals(T.array(T.natTestable, [] : [Nat])) ), test( "filter all", - List.toArray(List.filter(list, func _ = true)), + list.filter(func _ = true).toArray(), M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4, 5, 6])) ), test( "filter empty", - List.isEmpty(List.filter(List.empty(), func _ = true)), + List.empty().filter(func _ = true).isEmpty(), M.equals(T.bool(true)) ) ] @@ -779,22 +779,22 @@ run( [ test( "filterMap double evens", - List.toArray(List.filterMap(list, func x = if (x % 2 == 0) ?(x * 2) else null)), + list.filterMap(func x = if (x % 2 == 0) ?(x * 2) else null).toArray(), M.equals(T.array(T.natTestable, [0, 4, 8, 12])) ), test( "filterMap none", - List.toArray(List.filterMap(list, func _ = null)), + list.filterMap(func _ = null).toArray(), M.equals(T.array(T.natTestable, [] : [Nat])) ), test( "filterMap all", - List.toArray(List.filterMap(list, func x = ?(Nat.toText(x)))), + list.filterMap(func x = ?(Nat.toText(x))).toArray(), M.equals(T.array(T.textTestable, ["0", "1", "2", "3", "4", "5", "6"])) ), test( "filterMap empty", - List.isEmpty(List.filterMap(List.empty(), func x = ?x)), + List.empty().filterMap(func x = ?x).isEmpty(), M.equals(T.bool(true)) ) ] @@ -811,7 +811,7 @@ run( [ test( "sort", - List.sort(list, Nat.compare) |> List.toArray(list), + do { list.sortInPlace(Nat.compare); list.toArray() }, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |> M.equals(T.array(T.natTestable, _)) ) ] @@ -914,23 +914,23 @@ func runTest(name : Text, test : (Nat) -> Bool) { // Test cases func testNew(n : Nat) : Bool { let vec = List.empty(); - List.size(vec) == 0 + vec.size() == 0 }; func testInit(n : Nat) : Bool { let vec = List.repeat(1, n); - List.size(vec) == n and (n == 0 or (List.at(vec, 0) == 1 and List.at(vec, n - 1 : Nat) == 1)) + vec.size() == n and (n == 0 or (List.at(vec, 0) == 1 and List.at(vec, n - 1 : Nat) == 1)) }; func testAdd(n : Nat) : Bool { if (n == 0) return true; let vec = List.empty(); for (i in Nat.range(0, n)) { - List.add(vec, i) + vec.add(i) }; - if (List.size(vec) != n) { - Debug.print("Size mismatch: expected " # Nat.toText(n) # ", got " # Nat.toText(List.size(vec))); + if (vec.size() != n) { + Debug.print("Size mismatch: expected " # Nat.toText(n) # ", got " # Nat.toText(vec.size())); return false }; @@ -969,13 +969,13 @@ func testRemoveLast(n : Nat) : Bool { while (i > 0) { i -= 1; - let last = List.removeLast(vec); + let last = vec.removeLast(); if (last != ?i) { Debug.print("Unexpected value removed: expected ?" # Nat.toText(i) # ", got " # debug_show (last)); return false }; if (List.size(vec) != i) { - Debug.print("Unexpected size after removal: expected " # Nat.toText(i) # ", got " # Nat.toText(List.size(vec))); + Debug.print("Unexpected size after removal: expected " # Nat.toText(i) # ", got " # Nat.toText(vec.size())); return false } }; @@ -987,7 +987,7 @@ func testRemoveLast(n : Nat) : Bool { }; if (List.size(vec) != 0) { - Debug.print("List should be empty, but has size " # Nat.toText(List.size(vec))); + Debug.print("List should be empty, but has size " # Nat.toText(vec.size())); return false }; @@ -1045,60 +1045,60 @@ func testPut(n : Nat) : Bool { if (n == 0) { true } else { - List.put(vec, n - 1 : Nat, 100); - List.at(vec, n - 1 : Nat) == 100 + vec.put(n - 1 : Nat, 100); + vec.at(n - 1 : Nat) == 100 } }; func testClear(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - List.clear(vec); - List.size(vec) == 0 + vec.clear(); + vec.size() == 0 }; func testClone(n : Nat) : Bool { let vec1 = List.fromArray(Array.tabulate(n, func(i) = i)); - let vec2 = List.clone(vec1); - List.equal(vec1, vec2, Nat.equal) + let vec2 = vec1.clone(); + vec1.equal(vec2, Nat.equal) }; func testMap(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - let mapped = List.map(vec, func(x) = x * 2); - List.equal(mapped, List.fromArray(Array.tabulate(n, func(i) = i * 2)), Nat.equal) + let mapped = vec.map(func(x) = x * 2); + mapped.equal(List.fromArray(Array.tabulate(n, func(i) = i * 2)), Nat.equal) }; func testIndexOf(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(2 * n, func(i) = i % n)); if (n == 0) { - List.indexOf(vec, Nat.equal, 0) == null + vec.indexOf(Nat.equal, 0) == null } else { var allCorrect = true; for (i in Nat.range(0, n)) { - let index = List.indexOf(vec, Nat.equal, i); + let index = vec.indexOf(Nat.equal, i); if (index != ?i) { allCorrect := false; Debug.print("indexOf failed for i = " # Nat.toText(i) # ", expected ?" # Nat.toText(i) # ", got " # debug_show (index)) } }; - allCorrect and List.indexOf(vec, Nat.equal, n) == null + allCorrect and vec.indexOf(Nat.equal, n) == null } }; func testLastIndexOf(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(2 * n, func(i) = i % n)); if (n == 0) { - List.lastIndexOf(vec, Nat.equal, 0) == null + vec.lastIndexOf(Nat.equal, 0) == null } else { var allCorrect = true; for (i in Nat.range(0, n)) { - let index = List.lastIndexOf(vec, Nat.equal, i); + let index = vec.lastIndexOf(Nat.equal, i); if (index != ?(n + i)) { allCorrect := false; Debug.print("lastIndexOf failed for i = " # Nat.toText(i) # ", expected ?" # Nat.toText(n + i) # ", got " # debug_show (index)) } }; - allCorrect and List.lastIndexOf(vec, Nat.equal, n) == null + allCorrect and vec.lastIndexOf(Nat.equal, n) == null } }; @@ -1107,20 +1107,20 @@ func testContains(n : Nat) : Bool { // Check if it contains all elements from 0 to n-1 for (i in Nat.range(1, n + 1)) { - if (not List.contains(vec, Nat.equal, i)) { + if (not vec.contains(Nat.equal, i)) { Debug.print("List should contain " # Nat.toText(i) # " but it doesn't"); return false } }; // Check if it doesn't contain n (which should be out of range) - if (List.contains(vec, Nat.equal, n + 1)) { + if (vec.contains(Nat.equal, n + 1)) { Debug.print("List shouldn't contain " # Nat.toText(n + 1) # " but it does"); return false }; // Check if it doesn't contain n+1 (another out of range value) - if (List.contains(vec, Nat.equal, n + 2)) { + if (vec.contains(Nat.equal, n + 2)) { Debug.print("List shouldn't contain " # Nat.toText(n + 2) # " but it does"); return false }; @@ -1129,55 +1129,61 @@ func testContains(n : Nat) : Bool { }; func testReverse(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - List.reverseInPlace(vec); - List.equal(vec, List.fromArray(Array.tabulate(n, func(i) = n - 1 - i)), Nat.equal) + vec.reverseInPlace(); + vec.equal(List.fromArray(Array.tabulate(n, func(i) = n - 1 - i)), Nat.equal) }; func testSort(n : Nat) : Bool { - let vec = List.fromArray(Array.tabulate(n, func(i) = (i * 123) % 100 - 50)); - List.sort(vec, Int.compare); - List.equal(vec, List.fromArray(Array.sort(Array.tabulate(n, func(i) = (i * 123) % 100 - 50), Int.compare)), Int.equal) + let array = Array.tabulate(n, func(i) = (i * 123) % 100 - 50); + let vec = List.fromArray(array); + + let sorted = vec.sort(Int.compare); + vec.sortInPlace(Int.compare); + + let expected = List.fromArray(Array.sort(array, Int.compare)); + + vec.equal(expected, Int.equal) and sorted.equal(expected, Int.equal) }; func testToArray(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - Array.equal(List.toArray(vec), Array.tabulate(n, func(i) = i), Nat.equal) + Array.equal(vec.toArray(), Array.tabulate(n, func(i) = i), Nat.equal) }; func testFromIter(n : Nat) : Bool { let iter = Nat.range(1, n + 1); let vec = List.fromIter(iter); - List.equal(vec, List.fromArray(Array.tabulate(n, func(i) = i + 1)), Nat.equal) + vec.equal(List.fromArray(Array.tabulate(n, func(i) = i + 1)), Nat.equal) }; func testFoldLeft(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i + 1)); - List.foldLeft(vec, "", func(acc, x) = acc # Nat.toText(x)) == Array.foldLeft(Array.tabulate(n, func(i) = i + 1), "", func(acc, x) = acc # Nat.toText(x)) + vec.foldLeft("", func(acc, x) = acc # Nat.toText(x)) == Array.foldLeft(Array.tabulate(n, func(i) = i + 1), "", func(acc, x) = acc # Nat.toText(x)) }; func testFoldRight(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i + 1)); - List.foldRight(vec, "", func(x, acc) = Nat.toText(x) # acc) == Array.foldRight(Array.tabulate(n, func(i) = i + 1), "", func(x, acc) = Nat.toText(x) # acc) + vec.foldRight("", func(x, acc) = Nat.toText(x) # acc) == Array.foldRight(Array.tabulate(n, func(i) = i + 1), "", func(x, acc) = Nat.toText(x) # acc) }; func testFilter(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - let evens = List.filter(vec, func x = x % 2 == 0); + let evens = vec.filter(func x = x % 2 == 0); let expectedEvens = List.fromArray(Array.tabulate((n + 1) / 2, func(i) = i * 2)); - if (not List.equal(evens, expectedEvens, Nat.equal)) { + if (not evens.equal(expectedEvens, Nat.equal)) { Debug.print("Filter evens failed"); return false }; - let none = List.filter(vec, func _ = false); - if (not List.isEmpty(none)) { + let none = vec.filter(func _ = false); + if (not none.isEmpty()) { Debug.print("Filter none failed"); return false }; - let all = List.filter(vec, func _ = true); - if (not List.equal(all, vec, Nat.equal)) { + let all = vec.filter(func _ = true); + if (not all.equal(vec, Nat.equal)) { Debug.print("Filter all failed"); return false }; @@ -1188,21 +1194,21 @@ func testFilter(n : Nat) : Bool { func testFilterMap(n : Nat) : Bool { let vec = List.fromArray(Array.tabulate(n, func(i) = i)); - let doubledEvens = List.filterMap(vec, func x = if (x % 2 == 0) ?(x * 2) else null); + let doubledEvens = vec.filterMap(func x = if (x % 2 == 0) ?(x * 2) else null); let expectedDoubledEvens = List.fromArray(Array.tabulate((n + 1) / 2, func(i) = i * 4)); - if (not List.equal(doubledEvens, expectedDoubledEvens, Nat.equal)) { + if (not doubledEvens.equal(expectedDoubledEvens, Nat.equal)) { Debug.print("FilterMap doubled evens failed"); return false }; - let none = List.filterMap(vec, func _ = null); - if (not List.isEmpty(none)) { + let none = vec.filterMap(func _ = null); + if (not none.isEmpty()) { Debug.print("FilterMap none failed"); return false }; - let all = List.filterMap(vec, func x = ?x); - if (not List.equal(all, vec, Nat.equal)) { + let all = vec.filterMap(func x = ?x); + if (not all.equal(vec, Nat.equal)) { Debug.print("FilterMap all failed"); return false }; @@ -1249,20 +1255,20 @@ Test.suite( var blockSize = list.blocks.size(); var sizes = List.empty<(Nat, Nat)>(); - List.add(sizes, (blockSize, 0)); + sizes.add((blockSize, 0)); let expectedSize = 100_000; for (i in Nat.range(0, expectedSize)) { - List.add(list, i); + list.add(i); let size = list.blocks.size(); assert blockSize <= size; if (blockSize < size) { blockSize := size; - List.add(sizes, (blockSize, List.size(list))) + sizes.add((blockSize, list.size())) } }; - Test.expect.nat(List.size(list)).equal(expectedSize); + Test.expect.nat(list.size()).equal(expectedSize); // Check how block size grows with the number of elements let expectedBlockResizes = [ @@ -1286,7 +1292,7 @@ Test.suite( (512, 32_769), (768, 65_537) ]; - Test.expect.array<(Nat, Nat)>(List.toArray(sizes), Tuple2.makeToText(Nat.toText, Nat.toText), Tuple2.makeEqual(Nat.equal, Nat.equal)).equal(expectedBlockResizes) + Test.expect.array<(Nat, Nat)>(sizes.toArray(), Tuple2.makeToText(Nat.toText, Nat.toText), Tuple2.makeEqual(Nat.equal, Nat.equal)).equal(expectedBlockResizes) } ) } diff --git a/test/Map.test.mo b/test/Map.test.mo index 3cb67fc60..51c893770 100644 --- a/test/Map.test.mo +++ b/test/Map.test.mo @@ -43,7 +43,7 @@ run( "insert empty", do { let map = Map.empty(); - assert Map.insert(map, Nat.compare, 0, "0"); + assert map.insert(0, "0"); Iter.toArray(Map.entries(map)) }, M.equals(T.array(entryTestable, [(0, "0")])) @@ -52,7 +52,7 @@ run( "remove empty", do { let map = Map.empty(); - Map.remove(map, Nat.compare, 0); + map.remove(0); Iter.toArray(Map.entries(map)) }, M.equals(T.array<(Nat, Text)>(entryTestable, [])) @@ -61,7 +61,7 @@ run( "delete empty", do { let map = Map.empty(); - assert (not Map.delete(map, Nat.compare, 0)); + assert (not map.delete(0)); Iter.toArray(Map.entries(map)) }, M.equals(T.array<(Nat, Text)>(entryTestable, [])) @@ -70,7 +70,7 @@ run( "take absent", do { let map = Map.empty(); - Map.take(map, Nat.compare, 0) + map.take(0) }, M.equals(T.optional(T.textTestable, null : ?Text)) ), @@ -88,7 +88,7 @@ run( do { let original = Map.empty(); let clone = Map.clone(original); - Map.add(original, Nat.compare, 0, "0"); + original.add(0, "0"); Map.size(clone) }, M.equals(T.nat(0)) @@ -107,7 +107,7 @@ run( "contains key", do { let map = Map.empty(); - Map.containsKey(map, Nat.compare, 0) + map.containsKey(0) }, M.equals(T.bool(false)) ), @@ -115,7 +115,7 @@ run( "get absent", do { let map = Map.empty(); - Map.get(map, Nat.compare, 0) + map.get(0) }, M.equals(T.optional(T.textTestable, null : ?Text)) ), @@ -123,7 +123,7 @@ run( "update absent", do { let map = Map.empty(); - Map.swap(map, Nat.compare, 0, "0") + map.swap(0, "0") }, M.equals(T.optional(T.textTestable, null : ?Text)) ), @@ -131,7 +131,7 @@ run( "replace if exists", do { let map = Map.empty(); - assert (Map.replace(map, Nat.compare, 0, "0") == null); + assert (map.replace(0, "0") == null); Map.size(map) }, M.equals(T.nat(0)) @@ -150,7 +150,8 @@ run( do { let map1 = Map.empty(); let map2 = Map.empty(); - Map.equal(map1, map2, Nat.compare, Text.equal) + // Note: This is pretty neat, both the comparison for K as well as equals for V are implicit + map1.equal(map2) }, M.equals(T.bool(true)) ), @@ -183,7 +184,7 @@ run( test( "from iterator", do { - let map = Map.fromIter(Iter.fromArray<(Nat, Text)>([]), Nat.compare); + let map = Map.fromIter(Iter.fromArray<(Nat, Text)>([])); Map.size(map) }, M.equals(T.nat(0)) @@ -206,9 +207,7 @@ run( "filter", do { let input = Map.empty(); - let output = Map.filter( - input, - Nat.compare, + let output = input.filter( func(_, _) { Runtime.trap("test failed") } @@ -235,9 +234,7 @@ run( "filter map", do { let input = Map.empty(); - let output = Map.filterMap( - input, - Nat.compare, + let output = input.filterMap( func(_, _) { Runtime.trap("test failed") } @@ -304,7 +301,7 @@ run( "to text", do { let map = Map.empty(); - Map.toText(map, Nat.toText, func(value) { value }) + map.toText() }, M.equals(T.text("Map{}")) ), @@ -313,6 +310,7 @@ run( do { let map1 = Map.empty(); let map2 = Map.empty(); + // NOTE: Can't make both compare's implicit because of the name overlap assert (Map.compare(map1, map2, Nat.compare, Text.compare) == #equal); true }, diff --git a/test/Set.test.mo b/test/Set.test.mo index 66f2f8c17..931de8e79 100644 --- a/test/Set.test.mo +++ b/test/Set.test.mo @@ -30,7 +30,7 @@ run( "add empty", do { let set = Set.empty(); - Set.add(set, Nat.compare, 0); + set.add(0); Iter.toArray(Set.values(set)) }, M.equals(T.array(T.natTestable, [0])) @@ -39,7 +39,7 @@ run( "insert empty", do { let set = Set.empty(); - assert Set.insert(set, Nat.compare, 0); + assert set.insert(0); Iter.toArray(Set.values(set)) }, M.equals(T.array(T.natTestable, [0])) @@ -48,7 +48,7 @@ run( "remove empty", do { let set = Set.empty(); - Set.remove(set, Nat.compare, 0); + set.remove(0); Iter.toArray(Set.values(set)) }, M.equals(T.array(T.natTestable, [])) @@ -57,7 +57,7 @@ run( "delete empty", do { let set = Set.empty(); - assert (not Set.delete(set, Nat.compare, 0)); + assert (not set.delete(0)); Iter.toArray(Set.values(set)) }, M.equals(T.array(T.natTestable, [])) @@ -97,7 +97,7 @@ run( do { let set = Set.empty(); Set.add(set, Nat.compare, 0); - Set.contains(set, Nat.compare, 0) + set.contains(0) }, M.equals(T.bool(true)) ), @@ -105,7 +105,7 @@ run( "contains absent", do { let set = Set.empty(); - Set.contains(set, Nat.compare, 0) + set.contains(0) }, M.equals(T.bool(false)) ), @@ -123,7 +123,7 @@ run( do { let set1 = Set.empty(); let set2 = Set.empty(); - Set.equal(set1, set2, Nat.compare) + set1.equal(set2) }, M.equals(T.bool(true)) ), @@ -146,7 +146,7 @@ run( test( "from iterator", do { - let set = Set.fromIter(Iter.fromArray([]), Nat.compare); + let set = Set.fromIter(Iter.fromArray([])); Set.size(set) }, M.equals(T.nat(0)) @@ -169,9 +169,7 @@ run( "filter", do { let input = Set.empty(); - let output = Set.filter( - input, - Nat.compare, + let output = input.filter( func(_) { Runtime.trap("test failed") } @@ -184,9 +182,7 @@ run( "map", do { let input = Set.empty(); - let output = Set.map( - input, - Int.compare, + let output = input.map( func(_) { Runtime.trap("test failed") } @@ -199,9 +195,7 @@ run( "filter map", do { let input = Set.empty(); - let output = Set.filterMap( - input, - Int.compare, + let output = input.filterMap( func(_) { Runtime.trap("test failed") } @@ -268,7 +262,7 @@ run( "to text", do { let set = Set.empty(); - Set.toText(set, Nat.toText) + set.toText() }, M.equals(T.text("Set{}")) ), @@ -277,7 +271,7 @@ run( do { let set1 = Set.empty(); let set2 = Set.empty(); - assert (Set.compare(set1, set2, Nat.compare) == #equal); + assert (set1.compare(set2) == #equal); true }, M.equals(T.bool(true)) @@ -287,7 +281,7 @@ run( do { let set1 = Set.fromIter(Iter.fromArray([]), Nat.compare); let set2 = Set.clone(set1); - Set.isSubset(set1, set2, Nat.compare) + set1.isSubset(set2) }, M.equals(T.bool(true)) ), @@ -297,7 +291,7 @@ run( let set1 = Set.fromIter(Iter.fromArray([]), Nat.compare); let set2 = Set.clone(set1); let set3 = Set.clone(set2); - let combined = Set.join(Iter.fromArray([set1, set2, set3]), Nat.compare); + let combined = Set.join(Iter.fromArray([set1, set2, set3])); Set.size(combined) }, M.equals(T.nat(0)) @@ -309,8 +303,8 @@ run( let subSet2 = Set.clone(subSet1); let subSet3 = Set.clone(subSet2); let iterator = Iter.fromArray([subSet1, subSet2, subSet3]); - let setOfSets = Set.fromIter>(iterator, func(first, second) { Set.compare(first, second, Nat.compare) }); - let combined = Set.flatten(setOfSets, Nat.compare); + let setOfSets = Set.fromIter>(iterator, func(first, second) { first.compare(second) }); + let combined = Set.flatten(setOfSets); Set.size(combined) }, M.equals(T.nat(0)) diff --git a/test/pure/Map.prop.test.mo b/test/pure/Map.prop.test.mo index 5c2d35485..b71043e5d 100644 --- a/test/pure/Map.prop.test.mo +++ b/test/pure/Map.prop.test.mo @@ -432,4 +432,4 @@ run_all_props((1, 3), 0, 1, 10); run_all_props((1, 5), 5, 100, 100); run_all_props((1, 10), 10, 100, 100); run_all_props((1, 100), 20, 100, 100); -run_all_props((1, 1000), 100, 100, 100) +//run_all_props((1, 1000), 100, 100, 100) diff --git a/test/pure/Set.prop.test.mo b/test/pure/Set.prop.test.mo index b62b984eb..bf93bfe31 100644 --- a/test/pure/Set.prop.test.mo +++ b/test/pure/Set.prop.test.mo @@ -546,4 +546,4 @@ run_all_props((1, 3), 0, 1, 10); run_all_props((1, 5), 5, 100, 100); run_all_props((1, 10), 10, 100, 100); run_all_props((1, 100), 20, 100, 100); -run_all_props((1, 1000), 100, 100, 100) +//run_all_props((1, 1000), 100, 100, 100) diff --git a/validation/api/api.lock.json b/validation/api/api.lock.json index a4f7184a5..eb3b1d10d 100644 --- a/validation/api/api.lock.json +++ b/validation/api/api.lock.json @@ -4,12 +4,12 @@ "exports": [ "public func all(array : [T], predicate : T -> Bool) : Bool", "public func any(array : [T], predicate : T -> Bool) : Bool", - "public func binarySearch(array : [T], compare : (T, T) -> Order.Order, element : T) : { #found : Nat; #insertionIndex : Nat }", - "public func compare(array1 : [T], array2 : [T], compare : (T, T) -> Order.Order) : Order.Order", + "public func binarySearch(array : [T], compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat }", + "public func compare(array1 : [T], array2 : [T], compare : (implicit : (T, T) -> Order.Order)) : Order.Order", "public func concat(array1 : [T], array2 : [T]) : [T]", "public func empty() : [T]", "public func enumerate(array : [T]) : Types.Iter<(Nat, T)>", - "public func equal(array1 : [T], array2 : [T], equal : (T, T) -> Bool) : Bool", + "public func equal(array1 : [T], array2 : [T], equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(array : [T], f : T -> Bool) : [T]", "public func filterMap(array : [T], f : T -> ?R) : [R]", "public func find(array : [T], predicate : T -> Bool) : ?T", @@ -21,26 +21,27 @@ "public func forEach(array : [T], f : T -> ())", "public func fromIter(iter : Types.Iter) : [T]", "public func fromVarArray(varArray : [var T]) : [T]", - "public func indexOf(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat", + "public func indexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public func isEmpty(array : [T]) : Bool", "public func join(arrays : Types.Iter<[T]>) : [T]", "public func keys(array : [T]) : Types.Iter", - "public func lastIndexOf(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat", + "public func lastIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public func map(array : [T], f : T -> R) : [R]", "public func mapEntries(array : [T], f : (T, Nat) -> R) : [R]", "public func mapResult(array : [T], f : T -> Types.Result) : Types.Result<[R], E>", - "public func nextIndexOf(array : [T], equal : (T, T) -> Bool, element : T, fromInclusive : Nat) : ?Nat", - "public func prevIndexOf(array : [T], equal : (T, T) -> Bool, element : T, fromExclusive : Nat) : ?Nat", + "public func nextIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromInclusive : Nat) : ?Nat", + "public func prevIndexOf(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromExclusive : Nat) : ?Nat", "public func range(array : [T], fromInclusive : Int, toExclusive : Int) : Types.Iter", "public func repeat(item : T, size : Nat) : [T]", "public func reverse(array : [T]) : [T]", + "public type Self", "public func singleton(element : T) : [T]", "public func size(array : [T]) : Nat", "public func sliceToArray(array : [T], fromInclusive : Int, toExclusive : Int) : [T]", "public func sliceToVarArray(array : [T], fromInclusive : Int, toExclusive : Int) : [var T]", - "public func sort(array : [T], compare : (T, T) -> Order.Order) : [T]", + "public func sort(array : [T], compare : (implicit : (T, T) -> Order.Order)) : [T]", "public func tabulate(size : Nat, generator : Nat -> T) : [T]", - "public func toText(array : [T], f : T -> Text) : Text", + "public func toText(array : [T], f : (implicit : (toText : T -> Text))) : Text", "public func toVarArray(array : [T]) : [var T]", "public func values(array : [T]) : Types.Iter" ] @@ -61,6 +62,7 @@ "public func less(blob1 : Blob, blob2 : Blob) : Bool", "public func lessOrEqual(blob1 : Blob, blob2 : Blob) : Bool", "public func notEqual(blob1 : Blob, blob2 : Blob) : Bool", + "public type Self", "public func size(blob : Blob) : Nat", "public func toArray(blob : Blob) : [Nat8]", "public func toVarArray(blob : Blob) : [var Nat8]" @@ -77,6 +79,7 @@ "public func logicalNot(bool : Bool) : Bool", "public func logicalOr(a : Bool, b : Bool) : Bool", "public func logicalXor(a : Bool, b : Bool) : Bool", + "public type Self", "public func toText(bool : Bool) : Text" ] }, @@ -104,6 +107,7 @@ "public func less(a : Char, b : Char) : Bool", "public func lessOrEqual(a : Char, b : Char) : Bool", "public func notEqual(a : Char, b : Char) : Bool", + "public type Self", "public let toNat32 : (char : Char) -> Nat32", "public let toText : (char : Char) -> Text" ] @@ -134,7 +138,8 @@ "public func isCleanReject(error : Error) : Bool", "public func isRetryPossible(error : Error) : Bool", "public let message : (error : Error) -> Text", - "public let reject : (message : Text) -> Error" + "public let reject : (message : Text) -> Error", + "public type Self" ] }, { @@ -174,6 +179,7 @@ "public let pi : Float", "public func pow(x : Float, y : Float) : Float", "public func rem(x : Float, y : Float) : Float", + "public type Self", "public let sin : (x : Float) -> Float", "public let sqrt : (x : Float) -> Float", "public func sub(x : Float, y : Float) : Float", @@ -218,6 +224,7 @@ "public func rangeByInclusive(from : Int, to : Int, step : Int) : Iter.Iter", "public func rangeInclusive(from : Int, to : Int) : Iter.Iter", "public func rem(x : Int, y : Int) : Int", + "public type Self", "public func sub(x : Int, y : Int) : Int", "public func toNat(int : Int) : Nat", "public func toText(x : Int) : Text" @@ -272,6 +279,7 @@ "public func range(fromInclusive : Int16, toExclusive : Int16) : Iter.Iter", "public func rangeInclusive(from : Int16, to : Int16) : Iter.Iter", "public func rem(x : Int16, y : Int16) : Int16", + "public type Self", "public func sub(x : Int16, y : Int16) : Int16", "public func subWrap(x : Int16, y : Int16) : Int16", "public let toInt : Int16 -> Int", @@ -330,6 +338,7 @@ "public func range(fromInclusive : Int32, toExclusive : Int32) : Iter.Iter", "public func rangeInclusive(from : Int32, to : Int32) : Iter.Iter", "public func rem(x : Int32, y : Int32) : Int32", + "public type Self", "public func sub(x : Int32, y : Int32) : Int32", "public func subWrap(x : Int32, y : Int32) : Int32", "public let toInt : Int32 -> Int", @@ -387,6 +396,7 @@ "public func range(fromInclusive : Int64, toExclusive : Int64) : Iter.Iter", "public func rangeInclusive(from : Int64, to : Int64) : Iter.Iter", "public func rem(x : Int64, y : Int64) : Int64", + "public type Self", "public func sub(x : Int64, y : Int64) : Int64", "public func subWrap(x : Int64, y : Int64) : Int64", "public let toInt : Int64 -> Int", @@ -442,6 +452,7 @@ "public func range(fromInclusive : Int8, toExclusive : Int8) : Iter.Iter", "public func rangeInclusive(from : Int8, to : Int8) : Iter.Iter", "public func rem(x : Int8, y : Int8) : Int8", + "public type Self", "public func sub(x : Int8, y : Int8) : Int8", "public func subWrap(x : Int8, y : Int8) : Int8", "public let toInt : Int8 -> Int", @@ -466,7 +477,7 @@ "public func all(iter : Iter, f : T -> Bool) : Bool", "public func any(iter : Iter, f : T -> Bool) : Bool", "public func concat(a : Iter, b : Iter) : Iter", - "public func contains(iter : Iter, equal : (T, T) -> Bool, value : T) : Bool", + "public func contains(iter : Iter, equal : (implicit : (T, T) -> Bool), value : T) : Bool", "public func drop(iter : Iter, n : Nat) : Iter", "public func dropWhile(iter : Iter, f : T -> Bool) : Iter", "public func empty() : Iter", @@ -485,16 +496,17 @@ "public func infinite(item : T) : Iter", "public type Iter", "public func map(iter : Iter, f : T -> R) : Iter", - "public func max(iter : Iter, compare : (T, T) -> Order.Order) : ?T", - "public func min(iter : Iter, compare : (T, T) -> Order.Order) : ?T", + "public func max(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : ?T", + "public func min(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : ?T", "public func reduce(iter : Iter, combine : (T, T) -> T) : ?T", "public func repeat(item : T, count : Nat) : Iter", "public func reverse(iter : Iter) : Iter", "public func scanLeft(iter : Iter, initial : R, combine : (R, T) -> R) : Iter", "public func scanRight(iter : Iter, initial : R, combine : (T, R) -> R) : Iter", + "public type Self", "public func singleton(value : T) : Iter", "public func size(iter : Iter) : Nat", - "public func sort(iter : Iter, compare : (T, T) -> Order.Order) : Iter", + "public func sort(iter : Iter, compare : (implicit : (T, T) -> Order.Order)) : Iter", "public func step(iter : Iter, n : Nat) : Iter", "public func take(iter : Iter, n : Nat) : Iter", "public func takeWhile(iter : Iter, f : T -> Bool) : Iter", @@ -516,14 +528,14 @@ "public func all(list : List, predicate : T -> Bool) : Bool", "public func any(list : List, predicate : T -> Bool) : Bool", "public func at(list : List, index : Nat) : T", - "public func binarySearch(list : List, compare : (T, T) -> Order.Order, element : T) : { #found : Nat; #insertionIndex : Nat }", + "public func binarySearch(list : List, compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat }", "public func clear(list : List)", "public func clone(list : List) : List", - "public func compare(list1 : List, list2 : List, compare : (T, T) -> Order.Order) : Order.Order", - "public func contains(list : List, equal : (T, T) -> Bool, element : T) : Bool", + "public func compare(list1 : List, list2 : List, compare : (implicit : (T, T) -> Order.Order)) : Order.Order", + "public func contains(list : List, equal : (implicit : (T, T) -> Bool), element : T) : Bool", "public func empty() : List", "public func enumerate(list : List) : Iter.Iter<(Nat, T)>", - "public func equal(list1 : List, list2 : List, equal : (T, T) -> Bool) : Bool", + "public func equal(list1 : List, list2 : List, equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(list : List, predicate : T -> Bool) : List", "public func filterMap(list : List, f : T -> ?R) : List", "public func find(list : List, predicate : T -> Bool) : ?T", @@ -539,15 +551,15 @@ "public func fromPure(pure : PureList.List) : List", "public func fromVarArray(array : [var T]) : List", "public func get(list : List, index : Nat) : ?T", - "public func indexOf(list : List, equal : (T, T) -> Bool, element : T) : ?Nat", + "public func indexOf(list : List, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public func isEmpty(list : List) : Bool", "public func keys(list : List) : Iter.Iter", "public func last(list : List) : ?T", - "public func lastIndexOf(list : List, equal : (T, T) -> Bool, element : T) : ?Nat", + "public func lastIndexOf(list : List, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public type List", "public func map(list : List, f : T -> R) : List", - "public func max(list : List, compare : (T, T) -> Order.Order) : ?T", - "public func min(list : List, compare : (T, T) -> Order.Order) : ?T", + "public func max(list : List, compare : (implicit : (T, T) -> Order.Order)) : ?T", + "public func min(list : List, compare : (implicit : (T, T) -> Order.Order)) : ?T", "public func put(list : List, index : Nat, value : T)", "public func removeLast(list : List) : ?T", "public func repeat(initValue : T, size : Nat) : List", @@ -557,12 +569,14 @@ "public func reverseForEachEntry(list : List, f : (Nat, T) -> ())", "public func reverseInPlace(list : List)", "public func reverseValues(list : List) : Iter.Iter", + "public type Self", "public func singleton(element : T) : List", "public func size(list : List) : Nat", - "public func sort(list : List, compare : (T, T) -> Order.Order)", + "public func sort(list : List, compare : (implicit : (T, T) -> Types.Order)) : List", + "public func sortInPlace(list : List, compare : (implicit : (T, T) -> Order.Order))", "public func toArray(list : List) : [T]", "public func toPure(list : List) : PureList.List", - "public func toText(list : List, f : T -> Text) : Text", + "public func toText(list : List, f : (implicit : (toText : T -> Text))) : Text", "public func toVarArray(list : List) : [var T]", "public func values(list : List) : Iter.Iter" ] @@ -570,44 +584,49 @@ { "name": "Map", "exports": [ - "public func add(map : Map, compare : (K, K) -> Order.Order, key : K, value : V)", + "public func add(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V)", "public func all(map : Map, predicate : (K, V) -> Bool) : Bool", "public func any(map : Map, predicate : (K, V) -> Bool) : Bool", - "public func assertValid(map : Map, compare : (K, K) -> Order.Order)", + "public func assertValid(map : Map, compare : (implicit : (K, K) -> Order.Order))", "public func clear(map : Map)", "public func clone(map : Map) : Map", - "public func compare(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order", - "public func containsKey(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool", - "public func delete(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool", + "public func compare(map1 : Map, map2 : Map, compareKey : (implicit : (compare : (K, K) -> Order.Order)), compareValue : (implicit : (compare : (V, V) -> Order.Order))) : Order.Order", + "public func containsKey(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool", + "public func delete(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool", "public func empty() : Map", "public func entries(map : Map) : Types.Iter<(K, V)>", - "public func entriesFrom( map : Map, compare : (K, K) -> Order.Order, key : K ) : Types.Iter<(K, V)>", - "public func equal(map1 : Map, map2 : Map, compareKey : (K, K) -> Types.Order, equalValue : (V, V) -> Bool) : Bool", - "public func filter(map : Map, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map", - "public func filterMap(map : Map, compare : (K, K) -> Order.Order, project : (K, V1) -> ?V2) : Map", + "public func entriesFrom( map : Map, compare : (implicit : (K, K) -> Order.Order), key : K ) : Types.Iter<(K, V)>", + "public func equal(map1 : Map, map2 : Map, compare : (implicit : (K, K) -> Types.Order), equal : (implicit : (V, V) -> Bool)) : Bool", + "public func filter(map : Map, compare : (implicit : (K, K) -> Order.Order), criterion : (K, V) -> Bool) : Map", + "public func filterMap(map : Map, compare : (implicit : (K, K) -> Order.Order), project : (K, V1) -> ?V2) : Map", "public func foldLeft( map : Map, base : A, combine : (A, K, V) -> A ) : A", "public func foldRight( map : Map, base : A, combine : (K, V, A) -> A ) : A", "public func forEach(map : Map, operation : (K, V) -> ())", - "public func fromIter(iter : Types.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map", - "public func fromPure(map : PureMap.Map, compare : (K, K) -> Order.Order) : Map", - "public func get(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V", - "public func insert(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : Bool", + "public func fromArray(array : [(K, V)], compare : (implicit : (K, K) -> Order.Order)) : Map", + "public func fromIter(iter : Types.Iter<(K, V)>, compare : (implicit : (K, K) -> Order.Order)) : Map", + "public func fromPure(map : PureMap.Map, compare : (implicit : (K, K) -> Order.Order)) : Map", + "public func fromVarArray(array : [var (K, V)], compare : (implicit : (K, K) -> Order.Order)) : Map", + "public func get(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V", + "public func insert(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : Bool", "public func isEmpty(map : Map) : Bool", "public func keys(map : Map) : Types.Iter", "public func map(map : Map, project : (K, V1) -> V2) : Map", "public type Map", "public func maxEntry(map : Map) : ?(K, V)", "public func minEntry(map : Map) : ?(K, V)", - "public func remove(map : Map, compare : (K, K) -> Order.Order, key : K)", - "public func replace(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : ?V", + "public func remove(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K)", + "public func replace(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : ?V", "public func reverseEntries(map : Map) : Types.Iter<(K, V)>", - "public func reverseEntriesFrom( map : Map, compare : (K, K) -> Order.Order, key : K ) : Types.Iter<(K, V)>", + "public func reverseEntriesFrom( map : Map, compare : (implicit : (K, K) -> Order.Order), key : K ) : Types.Iter<(K, V)>", + "public type Self", "public func singleton(key : K, value : V) : Map", "public func size(map : Map) : Nat", - "public func swap(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : ?V", - "public func take(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V", - "public func toPure(map : Map, compare : (K, K) -> Order.Order) : PureMap.Map", - "public func toText(map : Map, keyFormat : K -> Text, valueFormat : V -> Text) : Text", + "public func swap(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : ?V", + "public func take(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V", + "public func toArray(map : Map) : [(K, V)]", + "public func toPure(map : Map, compare : (implicit : (K, K) -> Order.Order)) : PureMap.Map", + "public func toText(map : Map, keyFormat : (implicit : (toText : K -> Text)), valueFormat : (implicit : (toText : V -> Text))) : Text", + "public func toVarArray(map : Map) : [var (K, V)]", "public func values(map : Map) : Types.Iter" ] }, @@ -638,6 +657,7 @@ "public func rangeByInclusive(from : Nat, to : Nat, step : Int) : Iter.Iter", "public func rangeInclusive(from : Nat, to : Nat) : Iter.Iter", "public func rem(x : Nat, y : Nat) : Nat", + "public type Self", "public func sub(x : Nat, y : Nat) : Nat", "public func toInt(nat : Nat) : Int", "public let toText : Nat -> Text" @@ -688,6 +708,7 @@ "public func range(fromInclusive : Nat16, toExclusive : Nat16) : Iter.Iter", "public func rangeInclusive(from : Nat16, to : Nat16) : Iter.Iter", "public func rem(x : Nat16, y : Nat16) : Nat16", + "public type Self", "public func sub(x : Nat16, y : Nat16) : Nat16", "public func subWrap(x : Nat16, y : Nat16) : Nat16", "public let toNat : Nat16 -> Nat", @@ -741,6 +762,7 @@ "public func range(fromInclusive : Nat32, toExclusive : Nat32) : Iter.Iter", "public func rangeInclusive(from : Nat32, to : Nat32) : Iter.Iter", "public func rem(x : Nat32, y : Nat32) : Nat32", + "public type Self", "public func sub(x : Nat32, y : Nat32) : Nat32", "public func subWrap(x : Nat32, y : Nat32) : Nat32", "public let toNat : Nat32 -> Nat", @@ -793,6 +815,7 @@ "public func range(fromInclusive : Nat64, toExclusive : Nat64) : Iter.Iter", "public func rangeInclusive(from : Nat64, to : Nat64) : Iter.Iter", "public func rem(x : Nat64, y : Nat64) : Nat64", + "public type Self", "public func sub(x : Nat64, y : Nat64) : Nat64", "public func subWrap(x : Nat64, y : Nat64) : Nat64", "public let toNat : Nat64 -> Nat", @@ -843,6 +866,7 @@ "public func range(fromInclusive : Nat8, toExclusive : Nat8) : Iter.Iter", "public func rangeInclusive(from : Nat8, to : Nat8) : Iter.Iter", "public func rem(x : Nat8, y : Nat8) : Nat8", + "public type Self", "public func sub(x : Nat8, y : Nat8) : Nat8", "public func subWrap(x : Nat8, y : Nat8) : Nat8", "public let toNat : Nat8 -> Nat", @@ -853,19 +877,20 @@ { "name": "Option", "exports": [ - "public func apply(x : ?A, f : ?(A -> B)) : ?B", - "public func chain(x : ?A, f : A -> ?B) : ?B", - "public func compare(x : ?A, y : ?A, cmp : (A, A) -> Types.Order) : Types.Order", - "public func equal(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool", - "public func flatten(x : ??A) : ?A", - "public func forEach(x : ?A, f : A -> ())", + "public func apply(x : ?T, f : ?(T -> R)) : ?R", + "public func chain(x : ?T, f : T -> ?R) : ?R", + "public func compare(x : ?T, y : ?T, cmp : (implicit : (compare : (T, T) -> Types.Order))) : Types.Order", + "public func equal(x : ?T, y : ?T, eq : (implicit : (equal : (T, T) -> Bool))) : Bool", + "public func flatten(x : ??T) : ?T", + "public func forEach(x : ?T, f : T -> ())", "public func get(x : ?T, default : T) : T", - "public func getMapped(x : ?A, f : A -> B, default : B) : B", + "public func getMapped(x : ?T, f : T -> R, default : R) : R", "public func isNull(x : ?Any) : Bool", "public func isSome(x : ?Any) : Bool", - "public func map(x : ?A, f : A -> B) : ?B", - "public func some(x : A) : ?A", - "public func toText(x : ?A, toText : A -> Text) : Text", + "public func map(x : ?T, f : T -> R) : ?R", + "public type Self", + "public func some(x : T) : ?T", + "public func toText(x : ?T, toText : (implicit : T -> Text)) : Text", "public func unwrap(x : ?T) : T" ] }, @@ -877,7 +902,8 @@ "public func isEqual(order : Order) : Bool", "public func isGreater(order : Order) : Bool", "public func isLess(order : Order) : Bool", - "public type Order" + "public type Order", + "public type Self" ] }, { @@ -901,6 +927,7 @@ "public func lessOrEqual(principal1 : Principal, principal2 : Principal) : Bool", "public func notEqual(principal1 : Principal, principal2 : Principal) : Bool", "public type Principal", + "public type Self", "public func toBlob(p : Principal) : Blob", "public func toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob", "public func toText(p : Principal) : Text" @@ -913,9 +940,9 @@ "public func empty() : PriorityQueue", "public func isEmpty(priorityQueue : PriorityQueue) : Bool", "public func peek(priorityQueue : PriorityQueue) : ?T", - "public func pop( priorityQueue : PriorityQueue, compare : (T, T) -> Order.Order ) : ?T", + "public func pop( priorityQueue : PriorityQueue, compare : (implicit : (T, T) -> Order.Order) ) : ?T", "public type PriorityQueue", - "public func push( priorityQueue : PriorityQueue, compare : (T, T) -> Order.Order, element : T )", + "public func push( priorityQueue : PriorityQueue, compare : (implicit : (T, T) -> Order.Order), element : T )", "public func singleton(element : T) : PriorityQueue", "public func size(priorityQueue : PriorityQueue) : Nat" ] @@ -927,16 +954,17 @@ "public func any(queue : Queue, predicate : T -> Bool) : Bool", "public func clear(queue : Queue)", "public func clone(queue : Queue) : Queue", - "public func compare(queue1 : Queue, queue2 : Queue, compare : (T, T) -> Order.Order) : Order.Order", - "public func contains(queue : Queue, equal : (T, T) -> Bool, element : T) : Bool", + "public func compare(queue1 : Queue, queue2 : Queue, compare : (implicit : (T, T) -> Order.Order)) : Order.Order", + "public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), element : T) : Bool", "public func empty() : Queue", - "public func equal(queue1 : Queue, queue2 : Queue, equal : (T, T) -> Bool) : Bool", + "public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(queue : Queue, criterion : T -> Bool) : Queue", "public func filterMap(queue : Queue, project : T -> ?U) : Queue", "public func forEach(queue : Queue, operation : T -> ())", "public func fromArray(array : [T]) : Queue", "public func fromIter(iter : Iter.Iter) : Queue", "public func fromPure(pureQueue : PureQueue.Queue) : Queue", + "public func fromVarArray(array : [var T]) : Queue", "public func isEmpty(queue : Queue) : Bool", "public func map(queue : Queue, project : T -> U) : Queue", "public func peekBack(queue : Queue) : ?T", @@ -946,11 +974,14 @@ "public func pushBack(queue : Queue, element : T)", "public func pushFront(queue : Queue, element : T)", "public type Queue", + "public func reverseValues(queue : Queue) : Iter.Iter", + "public type Self", "public func singleton(element : T) : Queue", "public func size(queue : Queue) : Nat", "public func toArray(queue : Queue) : [T]", "public func toPure(queue : Queue) : PureQueue.Queue", - "public func toText(queue : Queue, format : T -> Text) : Text", + "public func toText(queue : Queue, format : (implicit : (toText : T -> Text))) : Text", + "public func toVarArray(queue : Queue) : [var T]", "public func values(queue : Queue) : Iter.Iter" ] }, @@ -1006,8 +1037,8 @@ "public func assertErr(result : Result)", "public func assertOk(result : Result)", "public func chain( result : Result, f : Ok1 -> Result ) : Result", - "public func compare( result1 : Result, result2 : Result, compareOk : (Ok, Ok) -> Order.Order, compareErr : (Err, Err) -> Order.Order ) : Order.Order", - "public func equal( result1 : Result, result2 : Result, equalOk : (Ok, Ok) -> Bool, equalErr : (Err, Err) -> Bool ) : Bool", + "public func compare( result1 : Result, result2 : Result, compareOk : (implicit : (compare : (Ok, Ok) -> Order.Order)), compareErr : (implicit : (compare : (Err, Err) -> Order.Order)) ) : Order.Order", + "public func equal( result1 : Result, result2 : Result, equalOk : (implicit : (equal : Ok, Ok) -> Bool), equalErr : (implicit : (equal : (Err, Err) -> Bool)) ) : Bool", "public func flatten( result : Result, Err> ) : Result", "public func forErr(result : Result, f : Err -> ())", "public func forOk(result : Result, f : Ok -> ())", @@ -1018,6 +1049,7 @@ "public func mapErr( result : Result, f : Err1 -> Err2 ) : Result", "public func mapOk( result : Result, f : Ok1 -> Ok2 ) : Result", "public type Result", + "public type Self", "public func toOption(result : Result) : ?Ok", "public func toUpper( result : Result ) : { #Ok : Ok; #Err : Err }" ] @@ -1032,49 +1064,52 @@ { "name": "Set", "exports": [ - "public func add(set : Set, compare : (T, T) -> Order.Order, element : T)", - "public func addAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter)", + "public func add(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T)", + "public func addAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter)", "public func all(set : Set, predicate : T -> Bool) : Bool", "public func any(set : Set, predicate : T -> Bool) : Bool", - "public func assertValid(set : Set, compare : (T, T) -> Order.Order)", + "public func assertValid(set : Set, compare : (implicit : (T, T) -> Order.Order))", "public func clear(set : Set)", "public func clone(set : Set) : Set", - "public func compare(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Order.Order", - "public func contains(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool", - "public func delete(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool", - "public func deleteAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter) : Bool", - "public func difference(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func compare(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Order.Order", + "public func contains(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool", + "public func delete(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool", + "public func deleteAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter) : Bool", + "public func difference(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func empty() : Set", - "public func equal(set1 : Set, set2 : Set, compare : (T, T) -> Types.Order) : Bool", - "public func filter(set : Set, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set", - "public func filterMap(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set", - "public func flatten(setOfSets : Set>, compare : (T, T) -> Order.Order) : Set", + "public func equal(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Types.Order)) : Bool", + "public func filter(set : Set, compare : (implicit : (T, T) -> Order.Order), criterion : T -> Bool) : Set", + "public func filterMap(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> ?T2) : Set", + "public func flatten(setOfSets : Set>, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func foldLeft( set : Set, base : A, combine : (A, T) -> A ) : A", "public func foldRight( set : Set, base : A, combine : (T, A) -> A ) : A", "public func forEach(set : Set, operation : T -> ())", - "public func fromIter(iter : Types.Iter, compare : (T, T) -> Order.Order) : Set", - "public func fromPure(set : PureSet.Set, compare : (T, T) -> Order.Order) : Set", - "public func insert(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool", - "public func insertAll(set : Set, compare : (T, T) -> Order.Order, iter : Types.Iter) : Bool", - "public func intersection(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func fromArray(array : [T], compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func fromIter(iter : Types.Iter, compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func fromPure(set : PureSet.Set, compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func insert(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool", + "public func insertAll(set : Set, compare : (implicit : (T, T) -> Order.Order), iter : Types.Iter) : Bool", + "public func intersection(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func isEmpty(set : Set) : Bool", - "public func isSubset(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Bool", - "public func join(setIterator : Types.Iter>, compare : (T, T) -> Order.Order) : Set", - "public func map(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set", + "public func isSubset(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool", + "public func join(setIterator : Types.Iter>, compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func map(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> T2) : Set", "public func max(set : Set) : ?T", "public func min(set : Set) : ?T", - "public func remove(set : Set, compare : (T, T) -> Order.Order, element : T) : ()", - "public func retainAll(set : Set, compare : (T, T) -> Order.Order, predicate : T -> Bool) : Bool", + "public func remove(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : ()", + "public func retainAll(set : Set, compare : (implicit : (T, T) -> Order.Order), predicate : T -> Bool) : Bool", "public func reverseValues(set : Set) : Types.Iter", - "public func reverseValuesFrom( set : Set, compare : (T, T) -> Order.Order, element : T ) : Types.Iter", + "public func reverseValuesFrom( set : Set, compare : (implicit : (T, T) -> Order.Order), element : T ) : Types.Iter", + "public type Self", "public type Set", "public func singleton(element : T) : Set", "public func size(set : Set) : Nat", - "public func toPure(set : Set, compare : (T, T) -> Order.Order) : PureSet.Set", - "public func toText(set : Set, elementFormat : T -> Text) : Text", - "public func union(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func toArray(set : Set) : [T]", + "public func toPure(set : Set, compare : (implicit : (T, T) -> Order.Order)) : PureSet.Set", + "public func toText(set : Set, toText : (implicit : T -> Text)) : Text", + "public func union(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func values(set : Set) : Types.Iter", - "public func valuesFrom( set : Set, compare : (T, T) -> Order.Order, element : T ) : Types.Iter" + "public func valuesFrom( set : Set, compare : (implicit : (T, T) -> Order.Order), element : T ) : Types.Iter" ] }, { @@ -1084,15 +1119,17 @@ "public func any(stack : Stack, predicate : T -> Bool) : Bool", "public func clear(stack : Stack)", "public func clone(stack : Stack) : Stack", - "public func compare(stack1 : Stack, stack2 : Stack, compare : (T, T) -> Order.Order) : Order.Order", - "public func contains(stack : Stack, equal : (T, T) -> Bool, element : T) : Bool", + "public func compare(stack1 : Stack, stack2 : Stack, compare : (implicit : (T, T) -> Order.Order)) : Order.Order", + "public func contains(stack : Stack, equal : (implicit : (T, T) -> Bool), element : T) : Bool", "public func empty() : Stack", - "public func equal(stack1 : Stack, stack2 : Stack, equal : (T, T) -> Bool) : Bool", + "public func equal(stack1 : Stack, stack2 : Stack, equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(stack : Stack, predicate : T -> Bool) : Stack", "public func filterMap(stack : Stack, project : T -> ?U) : Stack", "public func forEach(stack : Stack, operation : T -> ())", + "public func fromArray(array : [T]) : Stack", "public func fromIter(iter : Types.Iter) : Stack", "public func fromPure(list : PureList.List) : Stack", + "public func fromVarArray(array : [var T]) : Stack", "public func get(stack : Stack, position : Nat) : ?T", "public func isEmpty(stack : Stack) : Bool", "public func map(stack : Stack, project : T -> U) : Stack", @@ -1100,12 +1137,16 @@ "public func pop(stack : Stack) : ?T", "public func push(stack : Stack, value : T)", "public func reverse(stack : Stack)", + "public func reverseValues(stack : Stack) : Iter.Iter", + "public type Self", "public func singleton(element : T) : Stack", "public func size(stack : Stack) : Nat", "public type Stack", "public func tabulate(size : Nat, generator : Nat -> T) : Stack", + "public func toArray(stack : Stack) : [T]", "public func toPure(stack : Stack) : PureList.List", - "public func toText(stack : Stack, format : T -> Text) : Text", + "public func toText(stack : Stack, format : (implicit : (toText : T -> Text))) : Text", + "public func toVarArray(stack : Stack) : [var T]", "public func values(stack : Stack) : Types.Iter" ] }, @@ -1113,7 +1154,7 @@ "name": "Text", "exports": [ "public func compare(t1 : Text, t2 : Text) : Order.Order", - "public func compareWith( t1 : Text, t2 : Text, cmp : (Char, Char) -> Order.Order ) : Order.Order", + "public func compareWith( t1 : Text, t2 : Text, cmp : (implicit : (compare : (Char, Char) -> Order.Order)) ) : Order.Order", "public func concat(t1 : Text, t2 : Text) : Text", "public func contains(t : Text, p : Pattern) : Bool", "public let decodeUtf8 : Blob -> ?Text", @@ -1137,6 +1178,7 @@ "public type Pattern", "public func replace(t : Text, p : Pattern, r : Text) : Text", "public func reverse(t : Text) : Text", + "public type Self", "public func size(t : Text) : Nat", "public func split(t : Text, p : Pattern) : Iter.Iter", "public func startsWith(t : Text, p : Pattern) : Bool", @@ -1160,6 +1202,7 @@ "exports": [ "public type Duration", "public let now : () -> Time", + "public type Self", "public type Time", "public type TimerId", "public func toNanoseconds(duration : Duration) : Nat" @@ -1170,6 +1213,7 @@ "exports": [ "public let cancelTimer : TimerId -> ()", "public func recurringTimer(duration : Time.Duration, job : () -> async ()) : TimerId", + "public type Self", "public func setTimer(duration : Time.Duration, job : () -> async ()) : TimerId", "public type TimerId" ] @@ -1221,13 +1265,13 @@ "exports": [ "public func all(array : [var T], predicate : T -> Bool) : Bool", "public func any(array : [var T], predicate : T -> Bool) : Bool", - "public func binarySearch(array : [var T], compare : (T, T) -> Order.Order, element : T) : { #found : Nat; #insertionIndex : Nat }", + "public func binarySearch(array : [var T], compare : (implicit : (T, T) -> Order.Order), element : T) : { #found : Nat; #insertionIndex : Nat }", "public func clone(array : [var T]) : [var T]", - "public func compare(array1 : [var T], array2 : [var T], compare : (T, T) -> Order.Order) : Order.Order", + "public func compare(array1 : [var T], array2 : [var T], compare : (implicit : (T, T) -> Order.Order)) : Order.Order", "public func concat(array1 : [var T], array2 : [var T]) : [var T]", "public func empty() : [var T]", "public func enumerate(array : [var T]) : Types.Iter<(Nat, T)>", - "public func equal(array1 : [var T], array2 : [var T], equal : (T, T) -> Bool) : Bool", + "public func equal(array1 : [var T], array2 : [var T], equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(array : [var T], f : T -> Bool) : [var T]", "public func filterMap(array : [var T], f : T -> ?R) : [var R]", "public func find(array : [var T], predicate : T -> Bool) : ?T", @@ -1237,30 +1281,33 @@ "public func foldLeft(array : [var T], base : A, combine : (A, T) -> A) : A", "public func foldRight(array : [var T], base : A, combine : (T, A) -> A) : A", "public func forEach(array : [var T], f : T -> ())", + "public func fromArray(array : [T]) : [var T]", "public func fromIter(iter : Types.Iter) : [var T]", - "public func indexOf(array : [var T], equal : (T, T) -> Bool, element : T) : ?Nat", + "public func indexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public func isEmpty(array : [var T]) : Bool", "public func join(arrays : Types.Iter<[var T]>) : [var T]", "public func keys(array : [var T]) : Types.Iter", - "public func lastIndexOf(array : [var T], equal : (T, T) -> Bool, element : T) : ?Nat", + "public func lastIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat", "public func map(array : [var T], f : T -> R) : [var R]", "public func mapEntries(array : [var T], f : (T, Nat) -> R) : [var R]", "public func mapInPlace(array : [var T], f : T -> T)", "public func mapResult(array : [var T], f : T -> Result.Result) : Result.Result<[var R], E>", - "public func nextIndexOf(array : [var T], equal : (T, T) -> Bool, element : T, fromInclusive : Nat) : ?Nat", - "public func prevIndexOf(array : [var T], equal : (T, T) -> Bool, element : T, fromExclusive : Nat) : ?Nat", + "public func nextIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T, fromInclusive : Nat) : ?Nat", + "public func prevIndexOf(array : [var T], equal : (implicit : (T, T) -> Bool), element : T, fromExclusive : Nat) : ?Nat", "public func range(array : [var T], fromInclusive : Int, toExclusive : Int) : Types.Iter", "public func repeat(item : T, size : Nat) : [var T]", "public func reverse(array : [var T]) : [var T]", "public func reverseInPlace(array : [var T]) : ()", + "public type Self", "public func singleton(element : T) : [var T]", "public func size(array : [var T]) : Nat", "public func sliceToArray(array : [var T], fromInclusive : Int, toExclusive : Int) : [T]", "public func sliceToVarArray(array : [var T], fromInclusive : Int, toExclusive : Int) : [var T]", - "public func sort(array : [var T], compare : (T, T) -> Order.Order) : [var T]", - "public func sortInPlace(array : [var T], compare : (T, T) -> Order.Order) : ()", + "public func sort(array : [var T], compare : (implicit : (T, T) -> Order.Order)) : [var T]", + "public func sortInPlace(array : [var T], compare : (implicit : (T, T) -> Order.Order)) : ()", "public func tabulate(size : Nat, generator : Nat -> T) : [var T]", - "public func toText(array : [var T], f : T -> Text) : Text", + "public func toArray(varArray : [var T]) : [T]", + "public func toText(array : [var T], f : (implicit : (toText : T -> Text))) : Text", "public func values(array : [var T]) : Types.Iter" ] }, @@ -1269,7 +1316,9 @@ "exports": [ "public func allocate(obj : T) : WeakReference", "public func get(weakRef : WeakReference) : ?T", - "public func isLive(weakRef : WeakReference) : Bool" + "public func isLive(weakRef : WeakReference) : Bool", + "public type Self", + "public type WeakReference" ] }, { @@ -1298,13 +1347,13 @@ "public func all(list : List, f : T -> Bool) : Bool", "public func any(list : List, f : T -> Bool) : Bool", "public func chunks(list : List, n : Nat) : List>", - "public func compare(list1 : List, list2 : List, compareItem : (T, T) -> Order.Order) : Order.Order", + "public func compare(list1 : List, list2 : List, compareItem : (implicit : (compare : (T, T) -> Order.Order))) : Order.Order", "public func concat(list1 : List, list2 : List) : List", - "public func contains(list : List, equal : (T, T) -> Bool, item : T) : Bool", + "public func contains(list : List, equal : (implicit : (T, T) -> Bool), item : T) : Bool", "public func drop(list : List, n : Nat) : List", "public func empty() : List", "public func enumerate(list : List) : Iter.Iter<(Nat, T)>", - "public func equal(list1 : List, list2 : List, equalItem : (T, T) -> Bool) : Bool", + "public func equal(list1 : List, list2 : List, equalItem : (implicit : (equal : (T, T) -> Bool))) : Bool", "public func filter(list : List, f : T -> Bool) : List", "public func filterMap(list : List, f : T -> ?R) : List", "public func find(list : List, f : T -> Bool) : ?T", @@ -1323,19 +1372,20 @@ "public type List", "public func map(list : List, f : T1 -> T2) : List", "public func mapResult(list : List, f : T -> Result.Result) : Result.Result, E>", - "public func merge(list1 : List, list2 : List, compare : (T, T) -> Order.Order) : List", + "public func merge(list1 : List, list2 : List, compare : (implicit : (T, T) -> Order.Order)) : List", "public func partition(list : List, f : T -> Bool) : (List, List)", "public func popFront(list : List) : (?T, List)", "public func pushFront(list : List, item : T) : List", "public func repeat(item : T, n : Nat) : List", "public func reverse(list : List) : List", + "public type Self", "public func singleton(item : T) : List", "public func size(list : List) : Nat", "public func split(list : List, n : Nat) : (List, List)", "public func tabulate(n : Nat, f : Nat -> T) : List", "public func take(list : List, n : Nat) : List", "public func toArray(list : List) : [T]", - "public func toText(list : List, f : T -> Text) : Text", + "public func toText(list : List, f : (implicit : T -> Text)) : Text", "public func toVarArray(list : List) : [var T]", "public func values(list : List) : Iter.Iter", "public func zip(list1 : List, list2 : List) : List<(T, U)>", @@ -1345,38 +1395,39 @@ { "name": "pure/Map", "exports": [ - "public func add(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : Map", + "public func add(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : Map", "public func all(map : Map, pred : (K, V) -> Bool) : Bool", "public func any(map : Map, pred : (K, V) -> Bool) : Bool", - "public func assertValid(map : Map, compare : (K, K) -> Order.Order) : ()", - "public func compare(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order", - "public func containsKey(map : Map, compare : (K, K) -> Order.Order, key : K) : Bool", - "public func delete(map : Map, compare : (K, K) -> Order.Order, key : K) : (Map, Bool)", + "public func assertValid(map : Map, compare : (implicit : (K, K) -> Order.Order)) : ()", + "public func compare(map1 : Map, map2 : Map, compareKey : (implicit : (compare : (K, K) -> Order.Order)), compareValue : (implicit : (compare : (V, V) -> Order.Order))) : Order.Order", + "public func containsKey(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Bool", + "public func delete(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : (Map, Bool)", "public func empty() : Map", "public func entries(map : Map) : Iter.Iter<(K, V)>", - "public func equal(map1 : Map, map2 : Map, compareKey : (K, K) -> Order.Order, equalValue : (V, V) -> Bool) : Bool", - "public func filter(map : Map, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map", - "public func filterMap(map : Map, compare : (K, K) -> Order.Order, f : (K, V1) -> ?V2) : Map", + "public func equal(map1 : Map, map2 : Map, compare : (implicit : (K, K) -> Order.Order), equal : (implicit : (V, V) -> Bool)) : Bool", + "public func filter(map : Map, compare : (implicit : (K, K) -> Order.Order), criterion : (K, V) -> Bool) : Map", + "public func filterMap(map : Map, compare : (implicit : (K, K) -> Order.Order), f : (K, V1) -> ?V2) : Map", "public func foldLeft( map : Map, base : A, combine : (A, K, V) -> A ) : A", "public func foldRight( map : Map, base : A, combine : (K, V, A) -> A ) : A", "public func forEach(map : Map, operation : (K, V) -> ())", - "public func fromIter(iter : Iter.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map", - "public func get(map : Map, compare : (K, K) -> Order.Order, key : K) : ?V", - "public func insert(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, Bool)", + "public func fromIter(iter : Iter.Iter<(K, V)>, compare : (implicit : (K, K) -> Order.Order)) : Map", + "public func get(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : ?V", + "public func insert(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, Bool)", "public func isEmpty(map : Map) : Bool", "public func keys(map : Map) : Iter.Iter", "public func map(map : Map, f : (K, V1) -> V2) : Map", "public type Map", "public func maxEntry(map : Map) : ?(K, V)", "public func minEntry(map : Map) : ?(K, V)", - "public func remove(map : Map, compare : (K, K) -> Order.Order, key : K) : Map", - "public func replace(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, ?V)", + "public func remove(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : Map", + "public func replace(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, ?V)", "public func reverseEntries(map : Map) : Iter.Iter<(K, V)>", + "public type Self", "public func singleton(key : K, value : V) : Map", "public func size(map : Map) : Nat", - "public func swap(map : Map, compare : (K, K) -> Order.Order, key : K, value : V) : (Map, ?V)", - "public func take(map : Map, compare : (K, K) -> Order.Order, key : K) : (Map, ?V)", - "public func toText(map : Map, keyFormat : K -> Text, valueFormat : V -> Text) : Text", + "public func swap(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K, value : V) : (Map, ?V)", + "public func take(map : Map, compare : (implicit : (K, K) -> Order.Order), key : K) : (Map, ?V)", + "public func toText(map : Map, keyFormat : (implicit : (toText : K -> Text)), valueFormat : (implicit : (toText : V -> Text))) : Text", "public func values(map : Map) : Iter.Iter" ] }, @@ -1385,10 +1436,10 @@ "exports": [ "public func all(queue : Queue, predicate : T -> Bool) : Bool", "public func any(queue : Queue, predicate : T -> Bool) : Bool", - "public func compare(queue1 : Queue, queue2 : Queue, compareItem : (T, T) -> Order.Order) : Order.Order", - "public func contains(queue : Queue, equal : (T, T) -> Bool, item : T) : Bool", + "public func compare(queue1 : Queue, queue2 : Queue, compareItem : (implicit : (compare : (T, T) -> Order.Order))) : Order.Order", + "public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), item : T) : Bool", "public func empty() : Queue", - "public func equal(queue1 : Queue, queue2 : Queue, equal : (T, T) -> Bool) : Bool", + "public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(queue : Queue, predicate : T -> Bool) : Queue", "public func filterMap(queue : Queue, f : T -> ?U) : Queue", "public func forEach(queue : Queue, f : T -> ())", @@ -1404,10 +1455,11 @@ "public func pushFront(queue : Queue, element : T) : Queue", "public type Queue", "public func reverse(queue : Queue) : Queue", + "public type Self", "public func singleton(item : T) : Queue", "public func size(queue : Queue) : Nat", "public func toArray(queue : Queue) : [T]", - "public func toText(queue : Queue, f : T -> Text) : Text", + "public func toText(queue : Queue, f : (implicit : (toText : T -> Text))) : Text", "public func values(queue : Queue) : Iter.Iter" ] }, @@ -1416,10 +1468,10 @@ "exports": [ "public func all(queue : Queue, predicate : T -> Bool) : Bool", "public func any(queue : Queue, predicate : T -> Bool) : Bool", - "public func compare(queue1 : Queue, queue2 : Queue, comparison : (T, T) -> Types.Order) : Types.Order", - "public func contains(queue : Queue, eq : (T, T) -> Bool, item : T) : Bool", + "public func compare(queue1 : Queue, queue2 : Queue, compareItem : (implicit : (compare : (T, T) -> Types.Order))) : Types.Order", + "public func contains(queue : Queue, equal : (implicit : (T, T) -> Bool), item : T) : Bool", "public func empty() : Queue", - "public func equal(queue1 : Queue, queue2 : Queue, equality : (T, T) -> Bool) : Bool", + "public func equal(queue1 : Queue, queue2 : Queue, equal : (implicit : (T, T) -> Bool)) : Bool", "public func filter(queue : Queue, predicate : T -> Bool) : Queue", "public func filterMap(queue : Queue, f : T -> ?U) : Queue", "public func forEach(queue : Queue, f : T -> ())", @@ -1434,47 +1486,49 @@ "public func pushFront(queue : Queue, element : T) : Queue", "public type Queue", "public func reverse(queue : Queue) : Queue", + "public type Self", "public func singleton(element : T) : Queue", "public func size(queue : Queue) : Nat", - "public func toText(queue : Queue, f : T -> Text) : Text", + "public func toText(queue : Queue, f : (implicit : (toText : T -> Text))) : Text", "public func values(queue : Queue) : Iter.Iter" ] }, { "name": "pure/Set", "exports": [ - "public func add(set : Set, compare : (T, T) -> Order.Order, elem : T) : Set", + "public func add(set : Set, compare : (implicit : (T, T) -> Order.Order), elem : T) : Set", "public func all(set : Set, predicate : T -> Bool) : Bool", "public func any(s : Set, pred : T -> Bool) : Bool", - "public func assertValid(set : Set, compare : (T, T) -> Order.Order) : ()", - "public func compare(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Order.Order", - "public func contains(set : Set, compare : (T, T) -> Order.Order, element : T) : Bool", - "public func delete(set : Set, compare : (T, T) -> Order.Order, element : T) : (Set, Bool)", - "public func difference(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func assertValid(set : Set, compare : (implicit : (T, T) -> Order.Order)) : ()", + "public func compare(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Order.Order", + "public func contains(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Bool", + "public func delete(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : (Set, Bool)", + "public func difference(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func empty() : Set", - "public func equal(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Bool", - "public func filter(set : Set, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set", - "public func filterMap(set : Set, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set", - "public func flatten(setOfSets : Set>, compare : (T, T) -> Order.Order) : Set", + "public func equal(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool", + "public func filter(set : Set, compare : (implicit : (T, T) -> Order.Order), criterion : T -> Bool) : Set", + "public func filterMap(set : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> ?T2) : Set", + "public func flatten(setOfSets : Set>, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func foldLeft( set : Set, base : A, combine : (A, T) -> A ) : A", "public func foldRight( set : Set, base : A, combine : (T, A) -> A ) : A", "public func forEach(set : Set, operation : T -> ())", - "public func fromIter(iter : Iter.Iter, compare : (T, T) -> Order.Order) : Set", - "public func insert(set : Set, compare : (T, T) -> Order.Order, elem : T) : (Set, Bool)", - "public func intersection(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func fromIter(iter : Iter.Iter, compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func insert(set : Set, compare : (implicit : (T, T) -> Order.Order), elem : T) : (Set, Bool)", + "public func intersection(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func isEmpty(set : Set) : Bool", - "public func isSubset(s1 : Set, s2 : Set, compare : (T, T) -> Order.Order) : Bool", - "public func join(setIterator : Iter.Iter>, compare : (T, T) -> Order.Order) : Set", - "public func map(s : Set, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set", + "public func isSubset(s1 : Set, s2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Bool", + "public func join(setIterator : Iter.Iter>, compare : (implicit : (T, T) -> Order.Order)) : Set", + "public func map(s : Set, compare : (implicit : (T2, T2) -> Order.Order), project : T1 -> T2) : Set", "public func max(s : Set) : ?T", "public func min(s : Set) : ?T", - "public func remove(set : Set, compare : (T, T) -> Order.Order, element : T) : Set", + "public func remove(set : Set, compare : (implicit : (T, T) -> Order.Order), element : T) : Set", "public func reverseValues(set : Set) : Iter.Iter", + "public type Self", "public type Set", "public func singleton(element : T) : Set", "public func size(set : Set) : Nat", - "public func toText(set : Set, elementFormat : T -> Text) : Text", - "public func union(set1 : Set, set2 : Set, compare : (T, T) -> Order.Order) : Set", + "public func toText(set : Set, elementFormat : (implicit : (toText : T -> Text))) : Text", + "public func union(set1 : Set, set2 : Set, compare : (implicit : (T, T) -> Order.Order)) : Set", "public func values(set : Set) : Iter.Iter" ] }