Motiko 基础语法
Motoko 的设计力求最小化内置类型和操作。Motoko 没有提供内置类型,而是提供了一个基础模块库来处理多种常见操作并使语言感觉完整。这个基础库仍在不断发展,包含支持核心功能的模块,所有基础库 API 都会随着时间的推移而发生不同程度的变化。您应该特别注意,基础库中包含的模块和函数的大小和数量可能会急剧增加,对基础库模块的更新可能会引入重大更改,需要您更新程序以保持兼容。
- 从基础库导入
要从基础库导入,请使用import
关键字,后跟本地模块名称和 URL,import
声明可以在其中找到要导入的模块。例如:
import Debug "mo:base/Debug";
Debug.print("hello world");
此示例说明如何mo:
使用base/
基本库路径和模块名称导入 Motoko 代码(由前缀表示)Debug
。您还可以使用相对路径导入 Motoko 代码和其他模块。例如,如果您在与主程序types.mo
相同的文件夹中创建了一个 Motoko 程序,您可以将它包含在一个像这样的导入声明中:
import Types "./types";
- 查看基础库模块
您可以在motoko-base开源存储库中找到 Motoko 基础模块的源代码和文档。存储库中有为 Motoko 基础库生成当前文档的本地副本的说明。
您还可以在开发人员中心的任何页面中使用搜索来搜索文档。
基本类型
以下为全英,可自行简单翻译
Array
Functions on Arrays
equal
func equal<A>(a : [A], b : [A], eq : (A, A) -> Bool) : Bool
Test if two arrays contain equal values
append
func append<A>(xs : [A], ys : [A]) : [A]
Append the values of two input arrays
sort
func sort<A>(xs : [A], cmp : (A, A) -> Order.Order) : [A]
Sorts the given array according to the cmp
function. This is a stable sort.
1
2
3
4
import Array "mo:base/Array";
import Nat "mo:base/Nat";
let xs = [4, 2, 6, 1, 5];
assert(Array.sort(xs, Nat.compare) == [1, 2, 4, 5, 6])
Run
sortInPlace
func sortInPlace<A>(xs : [var A], cmp : (A, A) -> Order.Order)
Sorts the given array in place according to the cmp
function. This is a stable sort.
1
2
3
4
5
import Array "mo:base/Array";
import Nat "mo:base/Nat";
let xs : [var Nat] = [4, 2, 6, 1, 5];
xs.sort(Nat.compare);
assert(Array.freeze(xs) == [1, 2, 4, 5, 6])
Run
chain
func chain<A, B>(xs : [A], f : A -> [B]) : [B]
Transform each array value into zero or more output values, appended in order
filter
func filter<A>(xs : [A], f : A -> Bool) : [A]
Output array contains each array-value if and only if the predicate is true; ordering retained.
mapFilter
func mapFilter<A, B>(xs : [A], f : A -> ?B) : [B]
Output array contains each transformed optional value; ordering retained.
foldLeft
func foldLeft<A, B>(xs : [A], initial : B, f : (B, A) -> B) : B
Aggregate and transform values into a single output value, by increasing indices.
foldRight
func foldRight<A, B>(xs : [A], initial : B, f : (A, B) -> B) : B
Aggregate and transform values into a single output value, by decreasing indices.
find
func find<A>(xs : [A], f : A -> Bool) : ?A
Returns optional first value for which predicate is true
freeze
func freeze<A>(xs : [var A]) : [A]
Transform mutable array into immutable array
flatten
func flatten<A>(xs : [[A]]) : [A]
Transform an array of arrays into a single array, with retained array-value order.
map
func map<A, B>(xs : [A], f : A -> B) : [B]
Transform each value using a function, with retained array-value order.
mapEntries
func mapEntries<A, B>(xs : [A], f : (A, Nat) -> B) : [B]
Transform each entry (index-value pair) using a function.
mapResult
func mapResult<A, R, E>(xs : [A], f : A -> Result.Result<R, E>) : Result.Result<[R], E>
Maps a Result-returning function over an Array and returns either the first error or an array of successful values.
1
2
3
4
5
6
7
8
9
10
11
12
import Array "mo:base/Array";
import Result "mo:base/Result";
import Int "mo:base/Int";
func makeNatural(x : Int) : Result.Result<Nat, Text> =
if (x >= 0) {
#ok(Int.abs(x))
} else {
#err(Int.toText(x) # " is not a natural number.")
};
assert(Array.mapResult<Int, Nat, Text>([0, 1, 2], makeNatural) == #ok([0, 1, 2]));
assert(Array.mapResult([-1, 0, 1], makeNatural) == #err("-1 is not a natural number."));
Run
make
func make<A>(x : A) : [A]
Make an array from a single value.
vals
func vals<A>(xs : [A]) : I.Iter<A>
Returns xs.vals()
.
keys
func keys<A>(xs : [A]) : I.Iter<Nat>
Returns xs.keys()
.
thaw
func thaw<A>(xs : [A]) : [var A]
Transform an immutable array into a mutable array.
init
func init<A>(size : Nat, initVal : A) : [var A]
Initialize a mutable array with size
copies of the initial value.
tabulate
func tabulate<A>(size : Nat, gen : Nat -> A) : [A]
Initialize a mutable array of the given size, and use the gen
function to produce the initial value for every index.
tabulateVar
func tabulateVar<A>(size : Nat, gen : Nat -> A) : [var A]
Initialize a mutable array using a generation function
AssocList
Lists of key-value entries (“associations”).
Implements the same operations as library Trie
, but uses a linked-list of entries and no hashing.
AssocList
type AssocList<K, V> = List.List<(K, V)>
polymorphic association linked lists between keys and values
find
func find<K, V>(al : AssocList<K, V>, k : K, k_eq : (K, K) -> Bool) : ?V
Find the value associated with a given key, or null if absent.
replace
func replace<K, V>(al : AssocList<K, V>, k : K, k_eq : (K, K) -> Bool, ov : ?V) : (AssocList<K, V>, ?V)
replace the value associated with a given key, or add it, if missing. returns old value, or null, if no prior value existed.
diff
func diff<K, V, W>(al1 : AssocList<K, V>, al2 : AssocList<K, W>, keq : (K, K) -> Bool) : AssocList<K, V>
The entries of the final list consist of those pairs of the left list whose keys are not present in the right list; the values of the right list are irrelevant.
mapAppend
func mapAppend<K, V, W, X>(al1 : AssocList<K, V>, al2 : AssocList<K, W>, vbin : (?V, ?W) -> X) : AssocList<K, X>
Transform and combine the entries of two association lists.
disjDisjoint
func disjDisjoint<K, V, W, X>(al1 : AssocList<K, V>, al2 : AssocList<K, W>, vbin : (?V, ?W) -> X) : AssocList<K, X>
Specialized version of disj
, optimized for disjoint sub-spaces of keyspace (no matching keys).
disj
func disj<K, V, W, X>(al1 : AssocList<K, V>, al2 : AssocList<K, W>, keq : (K, K) -> Bool, vbin : (?V, ?W) -> X) : AssocList<K, X>
This operation generalizes the notion of “set union” to finite maps. Produces a “disjunctive image” of the two lists, where the values of matching keys are combined with the given binary operator.
For unmatched entries, the operator is still applied to create the value in the image. To accomodate these various situations, the operator accepts optional values, but is never applied to (null, null).
join
func join<K, V, W, X>(al1 : AssocList<K, V>, al2 : AssocList<K, W>, keq : (K, K) -> Bool, vbin : (V, W) -> X) : AssocList<K, X>
This operation generalizes the notion of “set intersection” to finite maps. Produces a “conjuctive image” of the two lists, where the values of matching keys are combined with the given binary operator, and unmatched entries are not present in the output.
fold
func fold<K, V, X>(al : AssocList<K, V>, nil : X, cons : (K, V, X) -> X) : X
Fold the entries based on the recursive list structure.
Blob
Binary blobs
Blob
type Blob = Prim.Types.Blob
An immutable, possibly empty sequence of bytes. Given b : Blob
:
b.size() : Nat
returns the number of bytes in the blob;b.vals() : Iter.Iter<Nat8>
returns an iterator to enumerate the bytes of the blob.
(Direct indexing of Blobs is not yet supported.)
hash
let hash : (b : Blob) -> Nat32
Returns a (non-cryptographic) hash of ‘b’
equal
func equal(x : Blob, y : Blob) : Bool
Returns x == y
.
notEqual
func notEqual(x : Blob, y : Blob) : Bool
Returns x != y
.
less
func less(x : Blob, y : Blob) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Blob, y : Blob) : Bool
Returns x ⇐ y
.
greater
func greater(x : Blob, y : Blob) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Blob, y : Blob) : Bool
Returns x >= y
.
compare
func compare(x : Blob, y : Blob) : {#less; #equal; #greater}
Returns the order of x
and y
.
fromArray
let fromArray : [Nat8] -> Blob
Creates a blob from an array of bytes, by copying each element.
fromArrayMut
let fromArrayMut : [var Nat8] -> Blob
Creates a blob from a mutable array of bytes, by copying each element.
toArray
let toArray : Blob -> [Nat8]
Creates an array of bytes from a blob, by copying each element.
toArrayMut
let toArrayMut : Blob -> [var Nat8]
Creates a mutable array of bytes from a blob, by copying each element.
Bool
Boolean type and operations.
While boolean operators _ and
and ``or
are short-circuiting, avoiding computation of the right argument when possible, the functions logand(
, *)*
and logor(
, _)
are strict and will always evaluate both of their arguments.
Bool
type Bool = Prim.Types.Bool
Booleans with constants true
and false
.
toText
func toText(x : Bool) : Text
Conversion.
logand
func logand(x : Bool, y : Bool) : Bool
Returns x and y
.
logor
func logor(x : Bool, y : Bool) : Bool
Returns x or y
.
logxor
func logxor(x : Bool, y : Bool) : Bool
Returns exclusive or of x
and y
, x != y
.
lognot
func lognot(x : Bool) : Bool
Returns not x
.
equal
func equal(x : Bool, y : Bool) : Bool
Returns x == y
.
notEqual
func notEqual(x : Bool, y : Bool) : Bool
Returns x != y
.
compare
func compare(x : Bool, y : Bool) : {#less; #equal; #greater}
Returns the order of x
and y
, where false < true
.
Buffer
Growing buffers
This module defines buffers that grow, with a general element type.
Why?
Motoko applications expose interfaces that use fixed-size arrays of general (user-defined) elements to represent sets, sequences and maps of application-specific elements.
The Array
module focuses on Motoko’s builtin arrays, whose size is fixed. Arrays do not permit general growth/appending, which is the focus here.
To create these arrays, and to consume them with ergonomic (imperative) code, and low API friction, developers can employ Buffer
objects.
Define Buf<X>
object type
A “Buffer” is a mutable sequence that can be extended by a single element or the contents of another buffer.
Buffer
class Buffer<X>(initCapacity : Nat)
Create a stateful buffer class encapsulating a mutable array.
The argument initCapacity
determines its initial capacity. The underlying mutable array grows by doubling when its current capacity is exceeded.
add
func add(elem : X)
Adds a single element to the buffer.
removeLast
func removeLast() : ?X
Removes the item that was inserted last and returns it or null
if no elements had been added to the Buffer.
append
func append(b : Buffer<X>)
Adds all elements in buffer b
to this buffer.
size
func size() : Nat
Returns the current number of elements.
clear
func clear()
Resets the buffer.
clone
func clone() : Buffer<X>
Returns a copy of this buffer.
vals
func vals() : { next : () -> ?X }
Returns an Iter
over the elements of this buffer.
toArray
func toArray() : [X]
Creates a new array containing this buffer’s elements.
toVarArray
func toVarArray() : [var X]
Creates a mutable array containing this buffer’s elements.
get
func get(i : Nat) : X
Gets the i
-th element of this buffer. Traps if i >= count
. Indexing is zero-based.
getOpt
func getOpt(i : Nat) : ?X
Gets the i
-th element of the buffer as an option. Returns null
when i >= count
. Indexing is zero-based.
put
func put(i : Nat, elem : X)
Overwrites the current value of the i
-entry of this buffer with elem
. Traps if the index is out of bounds. Indexing is zero-based.
CertifiedData
Certified data.
The Internet Computer allows canisters to store a small amount of data during update method processing so that during query call processing, the canister can obtain a certificate about that data.
This module provides a low-level interface to this API, aimed at advanced users and library implementors. See the Internet Computer Functional Specification and corresponding documentation for how to use this to make query calls to your canister tamperproof.
set
let set : (data : Blob) -> ()
Set the certified data.
Must be called from an update method, else traps. Must be passed a blob of at most 32 bytes, else traps.
getCertificate
let getCertificate : () -> ?Blob
Gets a certificate
Returns null
if no certificate is available, e.g. when processing an update call or inter-canister call. This returns a non-null
value only when processing a query call.
Char
Characters
Char
type Char = Prim.Types.Char
Characters represented as Unicode code points.
toNat32
let toNat32 : (c : Char) -> Nat32
Convert character c
to a word containing its Unicode scalar value.
fromNat32
let fromNat32 : (w : Nat32) -> Char
Convert w
to a character. Traps if w
is not a valid Unicode scalar value. Value w
is valid if, and only if, w < 0xD800 or (0xE000 ⇐ w and w ⇐ 0x10FFFF)
.
toText
let toText : (c : Char) -> Text
Convert character c
to single character text.
isDigit
func isDigit(c : Char) : Bool
Returns true
when c
is a decimal digit between 0
and 9
, otherwise false
.
isWhitespace
let isWhitespace : (c : Char) -> Bool
Returns the Unicode White_Space property of c
.
isLowercase
let isLowercase : (c : Char) -> Bool
Returns the Unicode Lowercase property of c
.
isUppercase
let isUppercase : (c : Char) -> Bool
Returns the Unicode Uppercase property of c
.
isAlphabetic
let isAlphabetic : (c : Char) -> Bool
Returns the Unicode Alphabetic property of c
.
equal
func equal(x : Char, y : Char) : Bool
Returns x == y
.
notEqual
func notEqual(x : Char, y : Char) : Bool
Returns x != y
.
less
func less(x : Char, y : Char) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Char, y : Char) : Bool
Returns x ⇐ y
.
greater
func greater(x : Char, y : Char) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Char, y : Char) : Bool
Returns x >= y
.
compare
func compare(x : Char, y : Char) : {#less; #equal; #greater}
Returns the order of x
and y
.
Debug
Debugging aids
let print : Text -> ()
print(t)
emits text t
to the debug output stream. How this stream is stored or displayed depends on the execution environment.
Deque
Functions for persistent, double-ended queues.
Deque
type Deque<T> = (List<T>, List<T>)
Double-ended queue
empty
func empty<T>() : Deque<T>
Empty queue
isEmpty
func isEmpty<T>(q : Deque<T>) : Bool
True when the queue is empty
pushFront
func pushFront<T>(q : Deque<T>, x : T) : Deque<T>
Insert a new element on the front end of the queue
peekFront
func peekFront<T>(q : Deque<T>) : ?T
Inspect the (optional) first element on the front end of the queue
popFront
func popFront<T>(q : Deque<T>) : ?(T, Deque<T>)
Remove the first element on the front end of the queue; Returns null when empty.
pushBack
func pushBack<T>(q : Deque<T>, x : T) : Deque<T>
Insert a new element on the back end of the queue
peekBack
func peekBack<T>(q : Deque<T>) : ?T
Inspect the (optional) first element on the back end of the queue
popBack
func popBack<T>(q : Deque<T>) : ?(Deque<T>, T)
Remove the first element on the back end of the queue; Returns null when empty.
Error
Error values and inspection.
The Error
type is the argument to throw
, parameter of catch
. The Error
type is opaque.
Error
type Error = Prim.Types.Error
Error values resulting from async
computations
ErrorCode
type ErrorCode = Prim.ErrorCode
Error codes (user and system), where module Prim
defines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type ErrorCode = {
// Fatal error.
#system_fatal;
// Transient error.
#system_transient;
// Destination invalid.
#destination_invalid;
// Explicit reject by canister code.
#canister_reject;
// Canister trapped.
#canister_error;
// Future error code (with unrecognized numeric code)
#future : Nat32;
};
Run
reject
let reject : (m : Text) -> Error
Create an error from message m
with code #canister_reject.
code
let code : (e : Error) -> ErrorCode
Returns the code of an error e
.
message
let message : (e : Error) -> Text
Returns the message of an error e
.
ExperimentalCycles
Managing cycles
Usage of the Internet Computer is measured, and paid for, in cycles. This library provides imperative operations for observing cycles, transferring cycles and observing refunds of cycles.
WARNING: This low-level API is experimental and likely to change or even disappear. Dedicated syntactic support for manipulating cycles may be added to the language in future, obsoleting this library.
NOTE: Since cycles measure computational resources, the value of balance()
can change from one call to the next.
balance
func balance() : (amount : Nat)
Returns the actor’s current balance of cycles as amount
.
available
func available() : (amount : Nat)
Returns the currently available amount
of cycles. The amount available is the amount received in the current call, minus the cumulative amount accept
ed by this call. On exit from the current shared function or async expression via return
or throw
any remaining available amount is automatically refunded to the caller/context.
accept
func accept(amount : Nat) : (accepted : Nat)
Transfers up to amount
from available()
to balance()
. Returns the amount actually transferred, which may be less than requested, for example, if less is available, or if canister balance limits are reached.
add
func add(amount : Nat) : ()
Indicates additional amount
of cycles to be transferred in the next call, that is, evaluation of a shared function call or async expression. Upon the call, but not before, the total amount of cycles add
ed since the last call is deducted from balance()
. If this total exceeds balance()
, the caller traps, aborting the call.
Note: the implicit register of added amounts is reset to zero on entry to a shared function and after each shared function call or resume from an await.
refunded
func refunded() : (amount : Nat)
Reports amount
of cycles refunded in the last await
of the current context, or zero if no await has occurred yet. Calling refunded()
is solely informational and does not affect balance()
. Instead, refunds are automatically added to the current balance, whether or not refunded
is used to observe them.
Float
64-bit Floating-point numbers
Float
type Float = Prim.Types.Float
64-bit floating point numbers.
pi
let pi : Float
Ratio of the circumference of a circle to its diameter.
e
let e : Float
Base of the natural logarithm.
abs
let abs : (x : Float) -> Float
Returns the absolute value of x
.
sqrt
let sqrt : (x : Float) -> Float
Returns the square root of x
.
ceil
let ceil : (x : Float) -> Float
Returns the smallest integral float greater than or equal to x
.
floor
let floor : (x : Float) -> Float
Returns the largest integral float less than or equal to x
.
trunc
let trunc : (x : Float) -> Float
Returns the nearest integral float not greater in magnitude than x
.
nearest
let nearest : (x : Float) -> Float
Returns the nearest integral float to x
.
copySign
let copySign : (x : Float, y : Float) -> Float
Returns x
if x
and y
have same sign, otherwise x
with negated sign.
min
let min : (x : Float, y : Float) -> Float
Returns the smaller value of x
and y
.
max
let max : (x : Float, y : Float) -> Float
Returns the larger value of x
and y
.
sin
let sin : (x : Float) -> Float
Returns the sine of the radian angle x
.
cos
let cos : (x : Float) -> Float
Returns the cosine of the radian angle x
.
tan
let tan : (x : Float) -> Float
Returns the tangent of the radian angle x
.
arcsin
let arcsin : (x : Float) -> Float
Returns the arc sine of x
in radians.
arccos
let arccos : (x : Float) -> Float
Returns the arc cosine of x
in radians.
arctan
let arctan : (x : Float) -> Float
Returns the arc tangent of x
in radians.
arctan2
let arctan2 : (y : Float, x : Float) -> Float
Given (y,x)
, returns the arc tangent in radians of y/x
based on the signs of both values to determine the correct quadrant.
exp
let exp : (x : Float) -> Float
Returns the value of e
raised to the x
-th power.
log
let log : (x : Float) -> Float
Returns the natural logarithm (base-e
) of x
.
format
func format(fmt : {#fix : Nat8; #exp : Nat8; #gen : Nat8; #hex : Nat8; #exact}, x : Float) : Text
Formatting. format(fmt, x)
formats x
to Text
according to the formatting directive fmt
, which can take one of the following forms:
#fix prec
as fixed-point format withprec
digits#exp prec
as exponential format withprec
digits#gen prec
as generic format withprec
digits#hex prec
as hexadecimal format withprec
digits#exact
as exact format that can be decoded without loss.
toText
let toText : Float -> Text
Conversion to Text. Use format(fmt, x)
for more detailed control.
toInt64
let toInt64 : Float -> Int64
Conversion to Int64 by truncating Float, equivalent to toInt64(trunc(f))
fromInt64
let fromInt64 : Int64 -> Float
Conversion from Int64.
toInt
let toInt : Float -> Int
Conversion to Int via Int64, equivalent to Int64.toInt(toInt64(trunc(f)))
fromInt
let fromInt : Int -> Float
Conversion from Int via Int64. May trap.
equal
func equal(x : Float, y : Float) : Bool
Returns x == y
.
notEqual
func notEqual(x : Float, y : Float) : Bool
Returns x != y
.
less
func less(x : Float, y : Float) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Float, y : Float) : Bool
Returns x ⇐ y
.
greater
func greater(x : Float, y : Float) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Float, y : Float) : Bool
Returns x >= y
.
compare
func compare(x : Float, y : Float) : {#less; #equal; #greater}
Returns the order of x
and y
.
neq
func neq(x : Float) : Float
Returns the negation of x
, -x
.
add
func add(x : Float, y : Float) : Float
Returns the sum of x
and y
, x + y
.
sub
func sub(x : Float, y : Float) : Float
Returns the difference of x
and y
, x - y
.
mul
func mul(x : Float, y : Float) : Float
Returns the product of x
and y
, x * y
.
div
func div(x : Float, y : Float) : Float
Returns the division of x
by y
, x / y
.
rem
func rem(x : Float, y : Float) : Float
Returns the remainder of x
divided by y
, x % y
.
pow
func pow(x : Float, y : Float) : Float
Returns x
to the power of y
, x ** y
.
Func
Functions on functions
(Most commonly used when programming in functional style using higher-order functions.)
compose
func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C
The composition of two functions f
and g
is a function that applies g
and then f
.
compose(f, g)(x) = f(g(x))copy
identity
func identity<A>(x : A) : A
The identity
function returns its argument.
import Func "mo:base/Func";
assert(Func.identity(10) == 10);
assert(Func.identity(true) == true);
Run
const
func const<A, B>(x : A) : B -> A
The const function is a curried function that accepts an argument x
, and then returns a function that discards its argument and always returns the x
.
import Func "mo:base/Func";
assert(Func.const<Nat, Text>(10)("hello") == 10);
assert(Func.const<Bool, Nat>(true)(20) == true);
Func
Functions on functions
(Most commonly used when programming in functional style using higher-order functions.)
compose
func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C
The composition of two functions f
and g
is a function that applies g
and then f
.
compose(f, g)(x) = f(g(x))copy
identity
func identity<A>(x : A) : A
The identity
function returns its argument.
import Func "mo:base/Func";
assert(Func.identity(10) == 10);
assert(Func.identity(true) == true);
Run
const
func const<A, B>(x : A) : B -> A
The const function is a curried function that accepts an argument x
, and then returns a function that discards its argument and always returns the x
.
import Func "mo:base/Func";
assert(Func.const<Nat, Text>(10)("hello") == 10);
assert(Func.const<Bool, Nat>(true)(20) == true);
Hash
Hash values
Hash
type Hash = Nat32
Hash values represent a string of hash bits, packed into a Nat32
.
length
let length : Nat
The hash length, always 31.
bit
func bit(h : Hash, pos : Nat) : Bool
Project a given bit from the bit vector.
equal
func equal(ha : Hash, hb : Hash) : Bool
Test if two hashes are equal
hash
func hash(i : Nat) : Hash
debugPrintBits
func debugPrintBits(bits : Hash)
debugPrintBitsRev
func debugPrintBitsRev(bits : Hash)
hashNat8
func hashNat8(key : [Hash]) : Hash
Jenkin’s one at a time:
https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time
The input type should actually be [Nat8]
. Note: Be sure to explode each Nat8
of a Nat32
into its own Nat32
, and to shift into lower 8 bits.
HashMap
Mutable hash map (aka Hashtable)
This module defines an imperative hash map (hash table), with a general key and value type.
It has a minimal object-oriented interface: get
, set
, delete
, count
and entries
.
The class is parameterized by the key’s equality and hash functions, and an initial capacity. However, as with the Buffer
class, no array allocation happens until the first set
.
Internally, table growth policy is very simple, for now: Double the current capacity when the expected bucket list size grows beyond a certain constant.
HashMap
class HashMap<K, V>(initCapacity : Nat, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash)
An imperative HashMap with a minimal object-oriented interface. Maps keys of type K
to values of type V
.
size
func size() : Nat
Returns the number of entries in this HashMap.
delete
func delete(k : K)
Deletes the entry with the key k
. Doesn’t do anything if the key doesn’t exist.
remove
func remove(k : K) : ?V
Removes the entry with the key k
and returns the associated value if it existed or null
otherwise.
get
func get(k : K) : ?V
Gets the entry with the key k
and returns its associated value if it existed or null
otherwise.
put
func put(k : K, v : V)
Insert the value v
at key k
. Overwrites an existing entry with key k
replace
func replace(k : K, v : V) : ?V
Insert the value v
at key k
and returns the previous value stored at k
or null
if it didn’t exist.
entries
func entries() : Iter.Iter<(K, V)>
Returns an iterator over the key value pairs in this HashMap
. Does not modify the HashMap
.
clone
func clone<K, V>(h : HashMap<K, V>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash) : HashMap<K, V>
clone cannot be an efficient object method, …but is still useful in tests, and beyond.
fromIter
func fromIter<K, V>(iter : Iter.Iter<(K, V)>, initCapacity : Nat, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash) : HashMap<K, V>
Clone from any iterator of key-value pairs
map
func map<K, V1, V2>(h : HashMap<K, V1>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash, mapFn : (K, V1) -> V2) : HashMap<K, V2>
mapFilter
func mapFilter<K, V1, V2>(h : HashMap<K, V1>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash, mapFn : (K, V1) -> ?V2) : HashMap<K, V2>
Heap
Priority Queue
This module provides purely-functional priority queue based on leftist heap
Tree
type Tree<T> = ?(Int, T, Tree<T>, Tree<T>)
Heap
class Heap<T>(ord : (T, T) -> O.Order)
share
func share() : Tree<T>
Get purely-functional representation
unsafeUnshare
func unsafeUnshare(t : Tree<T>)
Put purely-functional representation into class. Need to make sure the tree is constructed with the same compare function
put
func put(x : T)
Insert an element to the heap
peekMin
func peekMin() : ?T
Return the minimal element
deleteMin
func deleteMin()
Delete the minimal element
removeMin
func removeMin() : ?T
Remove the minimal element and return its value
fromIter
func fromIter<T>(iter : I.Iter<T>, ord : (T, T) -> O.Order) : Heap<T>
Convert iterator into a heap in O(N) time.
Int
Integer numbers
Most operations on integers (e.g. addition) are available as built-in operators (e.g. 1 + 1
). This module provides equivalent functions and Text
conversion.
Int
type Int = Prim.Types.Int
Infinite precision signed integers.
abs
let abs : Int -> Nat
Returns the absolute value of the number
toText
let toText : Int -> Text
Conversion.
min
func min(x : Int, y : Int) : Int
Returns the minimum of x
and y
.
max
func max(x : Int, y : Int) : Int
Returns the maximum of x
and y
.
hash
func hash(i : Int) : Hash.Hash
hashAcc
func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash
May go away (?) | |
---|---|
equal
func equal(x : Int, y : Int) : Bool
Returns x == y
.
notEqual
func notEqual(x : Int, y : Int) : Bool
Returns x != y
.
less
func less(x : Int, y : Int) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Int, y : Int) : Bool
Returns x ⇐ y
.
greater
func greater(x : Int, y : Int) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Int, y : Int) : Bool
Returns x >= y
.
compare
func compare(x : Int, y : Int) : {#less; #equal; #greater}
Returns the order of x
and y
.
neq
func neq(x : Int) : Int
Returns the negation of x
, -x
.
add
func add(x : Int, y : Int) : Int
Returns the sum of x
and y
, x + y
.
sub
func sub(x : Int, y : Int) : Int
Returns the difference of x
and y
, x - y
.
mul
func mul(x : Int, y : Int) : Int
Returns the product of x
and y
, x * y
.
div
func div(x : Int, y : Int) : Int
Returns the division of x
by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Int, y : Int) : Int
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Int, y : Int) : Int
Returns x
to the power of y
, x ** y
.
Int8
8-bit signed integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Int8
type Int8 = Prim.Types.Int8
8-bit signed integers.
toInt
let toInt : Int8 -> Int
Conversion.
fromInt
let fromInt : Int -> Int8
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Int8
Conversion. Wraps on overflow/underflow.
fromNat8
let fromNat8 : Nat8 -> Int8
Conversion. Wraps on overflow/underflow.
toNat8
let toNat8 : Int8 -> Nat8
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Int8) : Text
Returns the Text representation of x
.
abs
func abs(x : Int8) : Int8
Returns the absolute value of x
. Traps when x = -2^7
.
min
func min(x : Int8, y : Int8) : Int8
Returns the minimum of x
and y
.
max
func max(x : Int8, y : Int8) : Int8
Returns the maximum of x
and y
.
equal
func equal(x : Int8, y : Int8) : Bool
Returns x == y
.
notEqual
func notEqual(x : Int8, y : Int8) : Bool
Returns x != y
.
less
func less(x : Int8, y : Int8) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Int8, y : Int8) : Bool
Returns x ⇐ y
.
greater
func greater(x : Int8, y : Int8) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Int8, y : Int8) : Bool
Returns x >= y
.
compare
func compare(x : Int8, y : Int8) : {#less; #equal; #greater}
Returns the order of x
and y
.
neg
func neg(x : Int8) : Int8
Returns the negation of x
, -x
. Traps on overflow.
add
func add(x : Int8, y : Int8) : Int8
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Int8, y : Int8) : Int8
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Int8, y : Int8) : Int8
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Int8, y : Int8) : Int8
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Int8, y : Int8) : Int8
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Int8, y : Int8) : Int8
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Int8, y : Int8) : Int8
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Int8, y : Int8) : Int8
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Int8, y : Int8) : Int8
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Int8, y : Int8) : Int8
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Int8, y : Int8) : Int8
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Int8, y : Int8) : Int8
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Int8, y : Int8) : Int8
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Int8, y : Int8) : Int8
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Int8, p : Nat) : Bool
Returns the value of bit p mod 8
in x
, (x & 2^(p mod 8)) == 2^(p mod 8)
.
bitset
func bitset(x : Int8, p : Nat) : Int8
Returns the value of setting bit p mod 8
in x
to 1
.
bitclear
func bitclear(x : Int8, p : Nat) : Int8
Returns the value of clearing bit p mod 8
in x
to 0
.
bitflip
func bitflip(x : Int8, p : Nat) : Int8
Returns the value of flipping bit p mod 8
in x
.
bitcountNonZero
let bitcountNonZero : (x : Int8) -> Int8
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Int8) -> Int8
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Int8) -> Int8
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Int8, y : Int8) : Int8
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Int8, y : Int8) : Int8
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Int8, y : Int8) : Int8
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Int8, y : Int8) : Int8
Returns x
to the power of y
, x **% y
. Wraps on overflow. Traps if y < 0
.
Int16
16-bit signed integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Int16
type Int16 = Prim.Types.Int16
16-bit signed integers
toInt
let toInt : Int16 -> Int
Conversion.
fromInt
let fromInt : Int -> Int16
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Int16
Conversion. Wraps on overflow/underflow.
fromNat16
let fromNat16 : Nat16 -> Int16
Conversion. Wraps on overflow/underflow.
toNat16
let toNat16 : Int16 -> Nat16
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Int16) : Text
Returns the Text representation of x
.
abs
func abs(x : Int16) : Int16
Returns the absolute value of x
. Traps when x = -2^15
.
min
func min(x : Int16, y : Int16) : Int16
Returns the minimum of x
and y
.
max
func max(x : Int16, y : Int16) : Int16
Returns the maximum of x
and y
.
equal
func equal(x : Int16, y : Int16) : Bool
Returns x == y
.
notEqual
func notEqual(x : Int16, y : Int16) : Bool
Returns x != y
.
less
func less(x : Int16, y : Int16) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Int16, y : Int16) : Bool
Returns x ⇐ y
.
greater
func greater(x : Int16, y : Int16) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Int16, y : Int16) : Bool
Returns x >= y
.
compare
func compare(x : Int16, y : Int16) : {#less; #equal; #greater}
Returns the order of x
and y
.
neg
func neg(x : Int16) : Int16
Returns the negation of x
, -x
. Traps on overflow.
add
func add(x : Int16, y : Int16) : Int16
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Int16, y : Int16) : Int16
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Int16, y : Int16) : Int16
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Int16, y : Int16) : Int16
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Int16, y : Int16) : Int16
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Int16, y : Int16) : Int16
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Int16, y : Int16) : Int16
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Int16, y : Int16) : Int16
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Int16, y : Int16) : Int16
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Int16, y : Int16) : Int16
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Int16, y : Int16) : Int16
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Int16, y : Int16) : Int16
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Int16, y : Int16) : Int16
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Int16, y : Int16) : Int16
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Int16, p : Nat) : Bool
Returns the value of bit p mod 16
in x
, (x & 2^(p mod 16)) == 2^(p mod 16)
.
bitset
func bitset(x : Int16, p : Nat) : Int16
Returns the value of setting bit p mod 16
in x
to 1
.
bitclear
func bitclear(x : Int16, p : Nat) : Int16
Returns the value of clearing bit p mod 16
in x
to 0
.
bitflip
func bitflip(x : Int16, p : Nat) : Int16
Returns the value of flipping bit p mod 16
in x
.
bitcountNonZero
let bitcountNonZero : (x : Int16) -> Int16
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Int16) -> Int16
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Int16) -> Int16
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Int16, y : Int16) : Int16
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Int16, y : Int16) : Int16
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Int16, y : Int16) : Int16
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Int16, y : Int16) : Int16
Returns x
to the power of y
, x **% y
. Wraps on overflow. Traps if y < 0
.
Int32
32-bit signed integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Int32
type Int32 = Prim.Types.Int32
32-bit signed integers.
toInt
let toInt : Int32 -> Int
Conversion.
fromInt
let fromInt : Int -> Int32
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Int32
Conversion. Wraps on overflow/underflow.
fromNat32
let fromNat32 : Nat32 -> Int32
Conversion. Wraps on overflow/underflow.
toNat32
let toNat32 : Int32 -> Nat32
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Int32) : Text
Returns the Text representation of x
.
abs
func abs(x : Int32) : Int32
Returns the absolute value of x
. Traps when x = -2^31
.
min
func min(x : Int32, y : Int32) : Int32
Returns the minimum of x
and y
.
max
func max(x : Int32, y : Int32) : Int32
Returns the maximum of x
and y
.
equal
func equal(x : Int32, y : Int32) : Bool
Returns x == y
.
notEqual
func notEqual(x : Int32, y : Int32) : Bool
Returns x != y
.
less
func less(x : Int32, y : Int32) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Int32, y : Int32) : Bool
Returns x ⇐ y
.
greater
func greater(x : Int32, y : Int32) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Int32, y : Int32) : Bool
Returns x >= y
.
compare
func compare(x : Int32, y : Int32) : {#less; #equal; #greater}
Returns the order of x
and y
.
neg
func neg(x : Int32) : Int32
Returns the negation of x
, -x
. Traps on overflow.
add
func add(x : Int32, y : Int32) : Int32
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Int32, y : Int32) : Int32
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Int32, y : Int32) : Int32
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Int32, y : Int32) : Int32
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Int32, y : Int32) : Int32
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Int32, y : Int32) : Int32
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Int32, y : Int32) : Int32
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Int32, y : Int32) : Int32
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Int32, y : Int32) : Int32
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Int32, y : Int32) : Int32
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Int32, y : Int32) : Int32
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Int32, y : Int32) : Int32
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Int32, y : Int32) : Int32
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Int32, y : Int32) : Int32
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Int32, p : Nat) : Bool
Returns the value of bit p mod 16
in x
, (x & 2^(p mod 16)) == 2^(p mod 16)
.
bitset
func bitset(x : Int32, p : Nat) : Int32
Returns the value of setting bit p mod 16
in x
to 1
.
bitclear
func bitclear(x : Int32, p : Nat) : Int32
Returns the value of clearing bit p mod 16
in x
to 0
.
bitflip
func bitflip(x : Int32, p : Nat) : Int32
Returns the value of flipping bit p mod 16
in x
.
bitcountNonZero
let bitcountNonZero : (x : Int32) -> Int32
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Int32) -> Int32
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Int32) -> Int32
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Int32, y : Int32) : Int32
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Int32, y : Int32) : Int32
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Int32, y : Int32) : Int32
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Int32, y : Int32) : Int32
Returns x
to the power of y
, x **% y
. Wraps on overflow. Traps if y < 0
.
Int64
64-bit signed integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Int64
type Int64 = Prim.Types.Int64
64-bit signed integers.
toInt
let toInt : Int64 -> Int
Conversion.
fromInt
let fromInt : Int -> Int64
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Int64
Conversion. Wraps on overflow/underflow.
fromNat64
let fromNat64 : Nat64 -> Int64
Conversion. Wraps on overflow/underflow.
toNat64
let toNat64 : Int64 -> Nat64
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Int64) : Text
Returns the Text representation of x
.
abs
func abs(x : Int64) : Int64
Returns the absolute value of x
. Traps when x = -2^63
.
min
func min(x : Int64, y : Int64) : Int64
Returns the minimum of x
and y
.
max
func max(x : Int64, y : Int64) : Int64
Returns the maximum of x
and y
.
equal
func equal(x : Int64, y : Int64) : Bool
Returns x == y
.
notEqual
func notEqual(x : Int64, y : Int64) : Bool
Returns x != y
.
less
func less(x : Int64, y : Int64) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Int64, y : Int64) : Bool
Returns x ⇐ y
.
greater
func greater(x : Int64, y : Int64) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Int64, y : Int64) : Bool
Returns x >= y
.
compare
func compare(x : Int64, y : Int64) : {#less; #equal; #greater}
Returns the order of x
and y
.
neg
func neg(x : Int64) : Int64
Returns the negation of x
, -x
. Traps on overflow.
add
func add(x : Int64, y : Int64) : Int64
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Int64, y : Int64) : Int64
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Int64, y : Int64) : Int64
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Int64, y : Int64) : Int64
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Int64, y : Int64) : Int64
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Int64, y : Int64) : Int64
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Int64, y : Int64) : Int64
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Int64, y : Int64) : Int64
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Int64, y : Int64) : Int64
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Int64, y : Int64) : Int64
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Int64, y : Int64) : Int64
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Int64, y : Int64) : Int64
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Int64, y : Int64) : Int64
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Int64, y : Int64) : Int64
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Int64, p : Nat) : Bool
Returns the value of bit p mod 64
in x
, (x & 2^(p mod 64)) == 2^(p mod 64)
.
bitset
func bitset(x : Int64, p : Nat) : Int64
Returns the value of setting bit p mod 64
in x
to 1
.
bitclear
func bitclear(x : Int64, p : Nat) : Int64
Returns the value of clearing bit p mod 64
in x
to 0
.
bitflip
func bitflip(x : Int64, p : Nat) : Int64
Returns the value of flipping bit p mod 64
in x
.
bitcountNonZero
let bitcountNonZero : (x : Int64) -> Int64
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Int64) -> Int64
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Int64) -> Int64
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Int64, y : Int64) : Int64
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Int64, y : Int64) : Int64
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Int64, y : Int64) : Int64
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Int64, y : Int64) : Int64
Returns x
to the power of y
, x **% y
. Wraps on overflow. Traps if y < 0
.
Iter
Iterators
Iter
type Iter<T> = { next : () -> ?T }
An iterator that produces values of type T
. Calling next
returns null
when iteration is finished.
Iterators are inherently stateful. Calling next
“consumes” a value from the Iterator that cannot be put back, so keep that in mind when sharing iterators between consumers.
An iterater i
can be iterated over using
for (x in i) {
…do something with x…
}copy
range
class range(x : Nat, y : Int)
Creates an iterator that produces all Nat
s from x
to y
including both of the bounds.
1
2
3
4
5
6
import Iter "mo:base/Iter";
let iter = Iter.range(1, 3);
assert(?1 == iter.next());
assert(?2 == iter.next());
assert(?3 == iter.next());
assert(null == iter.next());
Run
next
func next() : ?Nat
revRange
class revRange(x : Int, y : Int)
Like range
but produces the values in the opposite order.
next
func next() : ?Int
iterate
func iterate<A>(xs : Iter<A>, f : (A, Nat) -> ())
Calls a function f
on every value produced by an iterator and discards the results. If you’re looking to keep these results use map
instead.
1
2
3
4
5
6
import Iter "mo:base/Iter";
var sum = 0;
Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {
sum += x;
});
assert(6 == sum)
Run
size
func size<A>(xs : Iter<A>) : Nat
Consumes an iterator and counts how many elements were produced (discarding them in the process).
map
func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B>
Takes a function and an iterator and returns a new iterator that lazily applies the function to every element produced by the argument iterator.
1
2
3
4
5
6
7
import Iter "mo:base/Iter";
let iter = Iter.range(1, 3);
let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });
assert(?2 == mappedIter.next());
assert(?4 == mappedIter.next());
assert(?6 == mappedIter.next());
assert(null == mappedIter.next());
Run
make
func make<A>(x : A) : Iter<A>
Creates an iterator that produces an infinite sequence of x
.
1
2
3
4
5
6
import Iter "mo:base/Iter";
let iter = Iter.make(10);
assert(?10 == iter.next());
assert(?10 == iter.next());
assert(?10 == iter.next());
// ...
Run
fromArray
func fromArray<A>(xs : [A]) : Iter<A>
Creates an iterator that produces the elements of an Array in ascending index order.
1
2
3
4
5
6
import Iter "mo:base/Iter";
let iter = Iter.fromArray([1, 2, 3]);
assert(?1 == iter.next());
assert(?2 == iter.next());
assert(?3 == iter.next());
assert(null == iter.next());
Run
fromArrayMut
func fromArrayMut<A>(xs : [var A]) : Iter<A>
Like fromArray
but for Arrays with mutable elements. Captures the elements of the Array at the time the iterator is created, so further modifications won’t be reflected in the iterator.
fromList
func fromList<A>(xs : List.List<A>) : Iter<A>
Like fromArray
but for Lists.
toArray
func toArray<A>(xs : Iter<A>) : [A]
Consumes an iterator and collects its produced elements in an Array.
import Iter "mo:base/Iter";
let iter = Iter.range(1, 3);
assert([1, 2, 3] == Iter.toArray(iter));
Run
toArrayMut
func toArrayMut<A>(xs : Iter<A>) : [var A]
Like toArray
but for Arrays with mutable elements.
toList
func toList<A>(xs : Iter<A>) : List.List<A>
Like toArray
but for Lists.
IterType
The Iterator type
Iter
type Iter<T> = { next : () -> ?T }
List
Purely-functional, singly-linked lists.
List
type List<T> = ?(T, List<T>)
nil
func nil<T>() : List<T>
Create an empty list.
isNil
func isNil<T>(l : List<T>) : Bool
Check whether a list is empty and return true if the list is empty.
push
func push<T>(x : T, l : List<T>) : List<T>
Construct a list by pre-pending a value. This function is similar to a list.cons(item)
function.
last
func last<T>(l : List<T>) : ?T
Return the last element of the list, if present.
pop
func pop<T>(l : List<T>) : (?T, List<T>)
Treat the list as a stack. This function combines the head
and (non-failing) tail
operations into one operation.
size
func size<T>(l : List<T>) : Nat
Return the length of the list.
get
func get<T>(l : List<T>, n : Nat) : ?T
Access any item in a list, zero-based.
Indexing into a list is a linear operation, and usually an indication that a list might not be the best data structure to use. | |
---|---|
reverse
func reverse<T>(l : List<T>) : List<T>
Reverses the list
iterate
func iterate<T>(l : List<T>, f : T -> ())
Call the given function with each list element in turn.
This function is equivalent to the app
function in Standard ML Basis, and the iter
function in OCaml.
map
func map<T, S>(l : List<T>, f : T -> S) : List<S>
Call the given function on each list element and collect the results in a new list.
filter
func filter<T>(l : List<T>, f : T -> Bool) : List<T>
Create a new list with only those elements of the original list for which the given function (often called the predicate) returns true.
partition
func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>)
Create two new lists from the results of a given function (f
). The first list only includes the elements for which the given function f
returns true and the second list only includes the elements for which the function returns false.
mapFilter
func mapFilter<T, S>(l : List<T>, f : T -> ?S) : List<S>
Call the given function on each list element, and collect the non-null results in a new list.
mapResult
func mapResult<A, R, E>(xs : List<A>, f : A -> Result.Result<R, E>) : Result.Result<List<R>, E>
Maps a Result-returning function over a List and returns either the first error or a list of successful values.
append
func append<T>(l : List<T>, m : List<T>) : List<T>
Append the elements from one list to another list.
flatten
func flatten<T>(l : List<List<T>>) : List<T>
Concatenate a list of lists.
In some languages, this operation is also known as a list join
.
take
func take<T>(l : List<T>, n : Nat) : List<T>
Returns the first n
elements of the given list. If the given list has fewer than n
elements, this function returns a copy of the full input list.
drop
func drop<T>(l : List<T>, n : Nat) : List<T>
Drop the first n
elements from the given list.
foldLeft
func foldLeft<T, S>(l : List<T>, a : S, f : (S, T) -> S) : S
Fold the list left-to-right using the given function (f
).
foldRight
func foldRight<T, S>(l : List<T>, a : S, f : (T, S) -> S) : S
Fold the list right-to-left using the given function (f
).
find
func find<T>(l : List<T>, f : T -> Bool) : ?T
Return the first element for which the given predicate f
is true, if such an element exists.
some
func some<T>(l : List<T>, f : T -> Bool) : Bool
Return true if there exists a list element for which the given predicate f
is true.
all
func all<T>(l : List<T>, f : T -> Bool) : Bool
Return true if the given predicate f
is true for all list elements.
merge
func merge<T>(l1 : List<T>, l2 : List<T>, lte : (T, T) -> Bool) : List<T>
Merge two ordered lists into a single ordered list. This function requires both list to be ordered as specified by the given relation lte
.
compare
func compare<T>(l1 : List<T>, l2 : List<T>, compElm : (T, T) -> Order.Order) : Order.Order
Compare two lists using lexicographic ordering specified by the given relation lte
.
equal
func equal<T>(l1 : List<T>, l2 : List<T>, eq : (T, T) -> Bool) : Bool
Compare two lists for equality as specified by the given relation eq
on the elements.
The function isEq(l1, l2)
is equivalent to lessThanEq(l1, l2) && lessThanEq(l2, l1)
, but the former is more efficient.
tabulate
func tabulate<T>(n : Nat, f : Nat -> T) : List<T>
Generate a list based on a length and a function that maps from a list index to a list element.
make
func make<X>(x : X) : List<X>
Create a list with exactly one element.
replicate
func replicate<X>(n : Nat, x : X) : List<X>
Create a list of the given length with the same value in each position.
zip
func zip<X, Y>(xs : List<X>, ys : List<Y>) : List<(X, Y)>
Create a list of pairs from a pair of lists.
If the given lists have different lengths, then the created list will have a length equal to the length of the smaller list.
zipWith
func zipWith<X, Y, Z>(xs : List<X>, ys : List<Y>, f : (X, Y) -> Z) : List<Z>
Create a list in which elements are calculated from the function f
and include elements occuring at the same position in the given lists.
If the given lists have different lengths, then the created list will have a length equal to the length of the smaller list.
split
func split<X>(n : Nat, xs : List<X>) : (List<X>, List<X>)
Split the given list at the given zero-based index.
chunks
func chunks<X>(n : Nat, xs : List<X>) : List<List<X>>
Split the given list into chunks of length n
. The last chunk will be shorter if the length of the given list does not divide by n
evenly.
fromArray
func fromArray<A>(xs : [A]) : List<A>
Convert an array into a list.
fromVarArray
func fromVarArray<A>(xs : [var A]) : List<A>
Convert a mutable array into a list.
toArray
func toArray<A>(xs : List<A>) : [A]
Create an array from a list.
toVarArray
func toVarArray<A>(xs : List<A>) : [var A]
Create a mutable array from a list.
Nat
Natural numbers
Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. 1 + 1
). This module provides equivalent functions and Text
conversion.
Nat
type Nat = Prim.Types.Nat
Infinite precision natural numbers.
toText
let toText : Nat -> Text
Conversion.
min
func min(x : Nat, y : Nat) : Nat
Returns the minimum of x
and y
.
max
func max(x : Nat, y : Nat) : Nat
Returns the maximum of x
and y
.
equal
func equal(x : Nat, y : Nat) : Bool
Returns x == y
.
notEqual
func notEqual(x : Nat, y : Nat) : Bool
Returns x != y
.
less
func less(x : Nat, y : Nat) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Nat, y : Nat) : Bool
Returns x ⇐ y
.
greater
func greater(x : Nat, y : Nat) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Nat, y : Nat) : Bool
Returns x >= y
.
compare
func compare(x : Nat, y : Nat) : {#less; #equal; #greater}
Returns the order of x
and y
.
add
func add(x : Nat, y : Nat) : Nat
Returns the sum of x
and y
, x + y
.
sub
func sub(x : Nat, y : Nat) : Nat
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Nat, y : Nat) : Nat
Returns the product of x
and y
, x * y
.
div
func div(x : Nat, y : Nat) : Nat
Returns the division of x
by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Nat, y : Nat) : Nat
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Nat, y : Nat) : Nat
Returns x
to the power of y
, x ** y
.
Nat8
8-bit unsigned integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Nat8
type Nat8 = Prim.Types.Nat8
8-bit natural numbers.
toNat
let toNat : Nat8 -> Nat
Conversion.
fromNat
let fromNat : Nat -> Nat8
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Nat8
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Nat8) : Text
Returns the Text representation of x
.
min
func min(x : Nat8, y : Nat8) : Nat8
Returns the minimum of x
and y
.
max
func max(x : Nat8, y : Nat8) : Nat8
Returns the maximum of x
and y
.
equal
func equal(x : Nat8, y : Nat8) : Bool
Returns x == y
.
notEqual
func notEqual(x : Nat8, y : Nat8) : Bool
Returns x != y
.
less
func less(x : Nat8, y : Nat8) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Nat8, y : Nat8) : Bool
Returns x ⇐ y
.
greater
func greater(x : Nat8, y : Nat8) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Nat8, y : Nat8) : Bool
Returns x >= y
.
compare
func compare(x : Nat8, y : Nat8) : {#less; #equal; #greater}
Returns the order of x
and y
.
add
func add(x : Nat8, y : Nat8) : Nat8
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Nat8, y : Nat8) : Nat8
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Nat8, y : Nat8) : Nat8
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Nat8, y : Nat8) : Nat8
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Nat8, y : Nat8) : Nat8
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Nat8, y : Nat8) : Nat8
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Nat8, y : Nat8) : Nat8
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Nat8, y : Nat8) : Nat8
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Nat8, y : Nat8) : Nat8
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Nat8, y : Nat8) : Nat8
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Nat8, y : Nat8) : Nat8
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Nat8, y : Nat8) : Nat8
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Nat8, y : Nat8) : Nat8
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Nat8, y : Nat8) : Nat8
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Nat8, p : Nat) : Bool
Returns the value of bit p mod 8
in x
, (x & 2^(p mod 8)) == 2^(p mod 8)
.
bitset
func bitset(x : Nat8, p : Nat) : Nat8
Returns the value of setting bit p mod 8
in x
to 1
.
bitclear
func bitclear(x : Nat8, p : Nat) : Nat8
Returns the value of clearing bit p mod 8
in x
to 0
.
bitflip
func bitflip(x : Nat8, p : Nat) : Nat8
Returns the value of flipping bit p mod 8
in x
.
bitcountNonZero
let bitcountNonZero : (x : Nat8) -> Nat8
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Nat8) -> Nat8
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Nat8) -> Nat8
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Nat8, y : Nat8) : Nat8
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Nat8, y : Nat8) : Nat8
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Nat8, y : Nat8) : Nat8
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Nat8, y : Nat8) : Nat8
Returns x
to the power of y
, x **% y
. Wraps on overflow.
Nat16
16-bit unsigned integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Nat16
type Nat16 = Prim.Types.Nat16
16-bit natural numbers.
toNat
let toNat : Nat16 -> Nat
Conversion.
fromNat
let fromNat : Nat -> Nat16
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Nat16
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Nat16) : Text
Returns the Text representation of x
.
min
func min(x : Nat16, y : Nat16) : Nat16
Returns the minimum of x
and y
.
max
func max(x : Nat16, y : Nat16) : Nat16
Returns the maximum of x
and y
.
equal
func equal(x : Nat16, y : Nat16) : Bool
Returns x == y
.
notEqual
func notEqual(x : Nat16, y : Nat16) : Bool
Returns x != y
.
less
func less(x : Nat16, y : Nat16) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Nat16, y : Nat16) : Bool
Returns x ⇐ y
.
greater
func greater(x : Nat16, y : Nat16) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Nat16, y : Nat16) : Bool
Returns x >= y
.
compare
func compare(x : Nat16, y : Nat16) : {#less; #equal; #greater}
Returns the order of x
and y
.
add
func add(x : Nat16, y : Nat16) : Nat16
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Nat16, y : Nat16) : Nat16
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Nat16, y : Nat16) : Nat16
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Nat16, y : Nat16) : Nat16
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Nat16, y : Nat16) : Nat16
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Nat16, y : Nat16) : Nat16
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Nat16, y : Nat16) : Nat16
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Nat16, y : Nat16) : Nat16
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Nat16, y : Nat16) : Nat16
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Nat16, y : Nat16) : Nat16
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Nat16, y : Nat16) : Nat16
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Nat16, y : Nat16) : Nat16
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Nat16, y : Nat16) : Nat16
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Nat16, y : Nat16) : Nat16
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Nat16, p : Nat) : Bool
Returns the value of bit p mod 16
in x
, (x & 2^(p mod 16)) == 2^(p mod 16)
.
bitset
func bitset(x : Nat16, p : Nat) : Nat16
Returns the value of setting bit p mod 16
in x
to 1
.
bitclear
func bitclear(x : Nat16, p : Nat) : Nat16
Returns the value of clearing bit p mod 16
in x
to 0
.
bitflip
func bitflip(x : Nat16, p : Nat) : Nat16
Returns the value of flipping bit p mod 16
in x
.
bitcountNonZero
let bitcountNonZero : (x : Nat16) -> Nat16
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Nat16) -> Nat16
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Nat16) -> Nat16
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Nat16, y : Nat16) : Nat16
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Nat16, y : Nat16) : Nat16
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Nat16, y : Nat16) : Nat16
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Nat16, y : Nat16) : Nat16
Returns x
to the power of y
, x **% y
. Wraps on overflow.
Nat32
32-bit unsigned integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Nat32
type Nat32 = Prim.Types.Nat32
32-bit natural numbers.
toNat
let toNat : Nat32 -> Nat
Conversion.
fromNat
let fromNat : Nat -> Nat32
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Nat32
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Nat32) : Text
Returns the Text representation of x
.
min
func min(x : Nat32, y : Nat32) : Nat32
Returns the minimum of x
and y
.
max
func max(x : Nat32, y : Nat32) : Nat32
Returns the maximum of x
and y
.
equal
func equal(x : Nat32, y : Nat32) : Bool
Returns x == y
.
notEqual
func notEqual(x : Nat32, y : Nat32) : Bool
Returns x != y
.
less
func less(x : Nat32, y : Nat32) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Nat32, y : Nat32) : Bool
Returns x ⇐ y
.
greater
func greater(x : Nat32, y : Nat32) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Nat32, y : Nat32) : Bool
Returns x >= y
.
compare
func compare(x : Nat32, y : Nat32) : {#less; #equal; #greater}
Returns the order of x
and y
.
add
func add(x : Nat32, y : Nat32) : Nat32
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Nat32, y : Nat32) : Nat32
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Nat32, y : Nat32) : Nat32
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Nat32, y : Nat32) : Nat32
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Nat32, y : Nat32) : Nat32
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Nat32, y : Nat32) : Nat32
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Nat32, y : Nat32) : Nat32
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Nat32, y : Nat32) : Nat32
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Nat32, y : Nat32) : Nat32
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Nat32, y : Nat32) : Nat32
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Nat32, y : Nat32) : Nat32
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Nat32, y : Nat32) : Nat32
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Nat32, y : Nat32) : Nat32
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Nat32, y : Nat32) : Nat32
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Nat32, p : Nat) : Bool
Returns the value of bit p mod 32
in x
, (x & 2^(p mod 32)) == 2^(p mod 32)
.
bitset
func bitset(x : Nat32, p : Nat) : Nat32
Returns the value of setting bit p mod 32
in x
to 1
.
bitclear
func bitclear(x : Nat32, p : Nat) : Nat32
Returns the value of clearing bit p mod 32
in x
to 0
.
bitflip
func bitflip(x : Nat32, p : Nat) : Nat32
Returns the value of flipping bit p mod 32
in x
.
bitcountNonZero
let bitcountNonZero : (x : Nat32) -> Nat32
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Nat32) -> Nat32
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Nat32) -> Nat32
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Nat32, y : Nat32) : Nat32
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Nat32, y : Nat32) : Nat32
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Nat32, y : Nat32) : Nat32
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Nat32, y : Nat32) : Nat32
Returns x
to the power of y
, x **% y
. Wraps on overflow.
Nat64
64-bit unsigned integers with checked arithmetic
Most operations are available as built-in operators (e.g. 1 + 1
).
Nat64
type Nat64 = Prim.Types.Nat64
64-bit natural numbers.
toNat
let toNat : Nat64 -> Nat
Conversion.
fromNat
let fromNat : Nat -> Nat64
Conversion. Traps on overflow/underflow.
fromIntWrap
let fromIntWrap : Int -> Nat64
Conversion. Wraps on overflow/underflow.
toText
func toText(x : Nat64) : Text
Returns the Text representation of x
.
min
func min(x : Nat64, y : Nat64) : Nat64
Returns the minimum of x
and y
.
max
func max(x : Nat64, y : Nat64) : Nat64
Returns the maximum of x
and y
.
equal
func equal(x : Nat64, y : Nat64) : Bool
Returns x == y
.
notEqual
func notEqual(x : Nat64, y : Nat64) : Bool
Returns x != y
.
less
func less(x : Nat64, y : Nat64) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Nat64, y : Nat64) : Bool
Returns x ⇐ y
.
greater
func greater(x : Nat64, y : Nat64) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Nat64, y : Nat64) : Bool
Returns x >= y
.
compare
func compare(x : Nat64, y : Nat64) : {#less; #equal; #greater}
Returns the order of x
and y
.
add
func add(x : Nat64, y : Nat64) : Nat64
Returns the sum of x
and y
, x + y
. Traps on overflow.
sub
func sub(x : Nat64, y : Nat64) : Nat64
Returns the difference of x
and y
, x - y
. Traps on underflow.
mul
func mul(x : Nat64, y : Nat64) : Nat64
Returns the product of x
and y
, x * y
. Traps on overflow.
div
func div(x : Nat64, y : Nat64) : Nat64
Returns the division of x by y
, x / y
. Traps when y
is zero.
rem
func rem(x : Nat64, y : Nat64) : Nat64
Returns the remainder of x
divided by y
, x % y
. Traps when y
is zero.
pow
func pow(x : Nat64, y : Nat64) : Nat64
Returns x
to the power of y
, x ** y
. Traps on overflow.
bitnot
func bitnot(x : Nat64, y : Nat64) : Nat64
Returns the bitwise negation of x
, ^x
.
bitand
func bitand(x : Nat64, y : Nat64) : Nat64
Returns the bitwise and of x
and y
, x & y
.
bitor
func bitor(x : Nat64, y : Nat64) : Nat64
Returns the bitwise or of x
and y
, x \| y
.
bitxor
func bitxor(x : Nat64, y : Nat64) : Nat64
Returns the bitwise exclusive or of x
and y
, x ^ y
.
bitshiftLeft
func bitshiftLeft(x : Nat64, y : Nat64) : Nat64
Returns the bitwise shift left of x
by y
, x << y
.
bitshiftRight
func bitshiftRight(x : Nat64, y : Nat64) : Nat64
Returns the bitwise shift right of x
by y
, x >> y
.
bitrotLeft
func bitrotLeft(x : Nat64, y : Nat64) : Nat64
Returns the bitwise rotate left of x
by y
, x <<> y
.
bitrotRight
func bitrotRight(x : Nat64, y : Nat64) : Nat64
Returns the bitwise rotate right of x
by y
, x <>> y
.
bittest
func bittest(x : Nat64, p : Nat) : Bool
Returns the value of bit p mod 64
in x
, (x & 2^(p mod 64)) == 2^(p mod 64)
.
bitset
func bitset(x : Nat64, p : Nat) : Nat64
Returns the value of setting bit p mod 64
in x
to 1
.
bitclear
func bitclear(x : Nat64, p : Nat) : Nat64
Returns the value of clearing bit p mod 64
in x
to 0
.
bitflip
func bitflip(x : Nat64, p : Nat) : Nat64
Returns the value of flipping bit p mod 64
in x
.
bitcountNonZero
let bitcountNonZero : (x : Nat64) -> Nat64
Returns the count of non-zero bits in x
.
bitcountLeadingZero
let bitcountLeadingZero : (x : Nat64) -> Nat64
Returns the count of leading zero bits in x
.
bitcountTrailingZero
let bitcountTrailingZero : (x : Nat64) -> Nat64
Returns the count of trailing zero bits in x
.
addWrap
func addWrap(x : Nat64, y : Nat64) : Nat64
Returns the sum of x
and y
, x +% y
. Wraps on overflow.
subWrap
func subWrap(x : Nat64, y : Nat64) : Nat64
Returns the difference of x
and y
, x -% y
. Wraps on underflow.
mulWrap
func mulWrap(x : Nat64, y : Nat64) : Nat64
Returns the product of x
and y
, x *% y
. Wraps on overflow.
powWrap
func powWrap(x : Nat64, y : Nat64) : Nat64
Returns x
to the power of y
, x **% y
. Wraps on overflow.
None
The absent value
The None
type represents a type with no value.
It is often used to type code that fails to return control (e.g. an infinite loop) or to designate impossible values (e.g. the type ?None
only contains null
).
None
type None = Prim.Types.None
The empty type. A subtype of all types.
impossible
let impossible : <A>None -> A
Turns an absurd value into an arbitrary type.
Option
Typesafe nulls
Optional values can be seen as a typesafe null
. A value of type ?Int
can be constructed with either null
or ?42
. The simplest way to get at the contents of an optional is to use pattern matching:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let optionalInt1 : ?Int = ?42;
let optionalInt2 : ?Int = null;
let int1orZero : Int = switch(optionalInt1) {
case null 0;
case (?int) int;
};
assert(int1orZero == 42);
let int2orZero : Int = switch(optionalInt2) {
case null 0;
case (?int) int;
};
assert(int2orZero == 0);
Run
The functions in this module capture some common operations when working with optionals that can be more succinct than using pattern matching.
get
func get<T>(x : ?T, default : T) : T
Unwraps an optional value, with a default value, i.e. get(?x, d) = x
and get(null, d) = d
.
getMapped
func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B
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
.
map
func map<A, B>(x : ?A, f : A -> B) : ?B
Applies a function to the wrapped value. `null’s are left untouched.
import Option "mo:base/Option";
assert(Option.map<Nat, Nat>(?(42), func x = x + 1) == ?(43));
assert(Option.map<Nat, Nat>(null, func x = x + 1) == null);
Run
iterate
func iterate<A>(x : ?A, f : A -> ())
Applies a function to the wrapped value, but discards the result. Use iterate
if you’re only interested in the side effect f
produces.
1
2
3
4
5
6
import Option "mo:base/Option";
var counter : Nat = 0;
Option.iterate(?(5), func (x : Nat) { counter += x });
assert(counter == 5);
Option.iterate(null, func (x : Nat) { counter += x });
assert(counter == 5);
Run
apply
func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B
Applies an optional function to an optional value. Returns null
if at least one of the arguments is null
.
chain
func chain<A, B>(x : ?A, f : A -> ?B) : ?B
Applies a function to an optional value. Returns null
if the argument is null
, or the function returns null
.
flatten
func flatten<A>(x : ??A) : ?A
Given an optional optional value, removes one layer of optionality.
1
2
3
4
import Option "mo:base/Option";
assert(Option.flatten(?(?(42))) == ?(42));
assert(Option.flatten(?(null)) == null);
assert(Option.flatten(null) == null);
Run
make
func make<A>(x : A) : ?A
Creates an optional value from a definite value.
import Option "mo:base/Option";
assert(Option.make(42) == ?(42));
Run
isSome
func isSome(x : ?Any) : Bool
Returns true if the argument is not null
, otherwise returns false.
isNull
func isNull(x : ?Any) : Bool
Returns true if the argument is null
, otherwise returns false.
assertSome
func assertSome(x : ?Any)
Asserts that the value is not null
; fails otherwise. Deprecated.
assertNull
func assertNull(x : ?Any)
Asserts that the value is null
; fails otherwise. Deprecated.
unwrap
func unwrap<T>(x : ?T) : T
Unwraps an optional value, i.e. unwrap(?x) = x
.
Order
Order
Order
type Order = {#less; #equal; #greater}
A type to represent an order.
isLess
func isLess(order : Order) : Bool
Check if an order is #less.
isEqual
func isEqual(order : Order) : Bool
Check if an order is #equal.
isGreater
func isGreater(order : Order) : Bool
Check if an order is #greater.
equal
func equal(o1 : Order, o2 : Order) : Bool
Returns true if only if o1
and o2
are the same ordering.
Prelude
General utilities
This prelude file proposes standard library features that may belong in the language (compiler-internal) prelude sometime, after some further experience and discussion. Until then, they live here.
nyi
func nyi() : None
Not yet implemented
Mark incomplete code with the nyi
and xxx
functions.
Each have calls are well-typed in all typing contexts, which trap in all execution contexts.
xxx
func xxx() : None
unreachable
func unreachable() : None
Mark unreachable code with the unreachable
function.
Calls are well-typed in all typing contexts, and they trap in all execution contexts.
Principal
IC principals (User and canister IDs)
Principal
type Principal = Prim.Types.Principal
Internet Computer principal identifiers. Convert to Blob
for access to bytes.
fromActor
let fromActor : (a : actor { }) -> Principal
Conversion.
toBlob
let toBlob : (p : Principal) -> Blob
Conversion.
toText
func toText(p : Principal) : Text
Conversion.
hash
func hash(principal : Principal) : Hash.Hash
fromText
func fromText(t : Text) : Principal
equal
func equal(x : Principal, y : Principal) : Bool
Returns x == y
.
notEqual
func notEqual(x : Principal, y : Principal) : Bool
Returns x != y
.
less
func less(x : Principal, y : Principal) : Bool
Returns x < y
.
lessOrEqual
func lessOrEqual(x : Principal, y : Principal) : Bool
Returns x ⇐ y
.
greater
func greater(x : Principal, y : Principal) : Bool
Returns x > y
.
greaterOrEqual
func greaterOrEqual(x : Principal, y : Principal) : Bool
Returns x >= y
.
compare
func compare(x : Principal, y : Principal) : {#less; #equal; #greater}
Returns the order of x
and y
.
RBTree
Red-Black Trees
Color
type Color = {#R; #B}
Node color: red or black.
Tree
type Tree<X, Y> = {#node : (Color, Tree<X, Y>, (X, ?Y), Tree<X, Y>); #leaf}
Ordered, (red-black) tree of entries.
RBTree
class RBTree<X, Y>(compareTo : (X, X) -> O.Order)
Create an order map from an order function for its keys.
share
func share() : Tree<X, Y>
Tree as sharable data.
Get non-OO, purely-functional representation: for drawing, pretty-printing and non-OO contexts (e.g., async args and results):
get
func get(x : X) : ?Y
Get the value associated with a given key.
replace
func replace(x : X, y : Y) : ?Y
Replace the value associated with a given key.
put
func put(x : X, y : Y)
Put an entry: A value associated with a given key.
delete
func delete(x : X)
Delete the entry associated with a given key.
remove
func remove(x : X) : ?Y
Remove the entry associated with a given key.
entries
func entries() : I.Iter<(X, Y)>
An iterator for the key-value entries of the map, in ascending key order.
iterator is persistent, like the tree itself
entriesRev
func entriesRev() : I.Iter<(X, Y)>
An iterator for the key-value entries of the map, in descending key order.
iterator is persistent, like the tree itself
iter
func iter<X, Y>(t : Tree<X, Y>, dir : {#fwd; #bwd}) : I.Iter<(X, Y)>
An iterator for the entries of the map, in ascending (#fwd
) or descending (#bwd
) order.
size
func size<X, Y>(t : Tree<X, Y>) : Nat
The size of the tree as the number of key-value entries.
Random
A module for obtaining randomness on the Internet Computer (IC).
This module provides the fundamentals for user abstractions to build on.
Dealing with randomness on a deterministic computing platform, such as the IC, is intricate. Some basic rules need to be followed by the user of this module to obtain (and maintain) the benefits of crypto- graphic randomness:
- cryptographic entropy (randomness source) is only obtainable asyncronously in discrete chunks of 256 bits (32-byte sized
Blob
s) - all bets must be closed before entropy is being asked for in order to decide them
- this implies that the same entropy (i.e.
Blob
) - or surplus entropy not utilised yet - cannot be used for a new round of bets without losing the cryptographic guarantees.
Concretely, the below class Finite
, as well as the *From
methods risk the carrying-over of state from previous rounds. These are provided for performance (and convenience) reasons, and need special care when used. Similar caveats apply for user-defined (pseudo) random number generators.
Finite
class Finite(entropy : Blob)
Drawing from a finite supply of entropy, Finite
provides methods to obtain random values. When the entropy is used up, null
is returned. Otherwise the outcomes’ distributions are stated for each method. The uniformity of outcomes is guaranteed only when the supplied entropy is originally obtained by the blob()
call, and is never reused.
byte
func byte() : ?Nat8
Uniformly distributes outcomes in the numeric range [0 … 255]. Consumes 1 byte of entropy.
coin
func coin() : ?Bool
Simulates a coin toss. Both outcomes have equal probability. Consumes 1 bit of entropy (amortised).
range
func range(p : Nat8) : ?Nat
Uniformly distributes outcomes in the numeric range [0 … 2^p - 1]. Consumes ⌈p/8⌉ bytes of entropy.
binomial
func binomial(n : Nat8) : ?Nat8
Counts the number of heads in n
fair coin tosses. Consumes ⌈p/8⌉ bytes of entropy.
byteFrom
func byteFrom(seed : Blob) : Nat8
Distributes outcomes in the numeric range [0 … 255]. Seed blob must contain at least a byte.
coinFrom
func coinFrom(seed : Blob) : Bool
Simulates a coin toss. Seed blob must contain at least a byte.
blob
let blob : shared () -> async Blob
Obtains a full blob (32 bytes) worth of fresh entropy.
rangeFrom
func rangeFrom(p : Nat8, seed : Blob) : Nat
Distributes outcomes in the numeric range [0 … 2^p - 1]. Seed blob must contain at least ((p+7) / 8) bytes.
binomialFrom
func binomialFrom(n : Nat8, seed : Blob) : Nat8
Counts the number of heads in n
coin tosses. Seed blob must contain at least ((n+7) / 8) bytes.
Result
Error handling with the Result type.
Result
type Result<Ok, Err> = {#ok : Ok; #err : Err}
Result<Ok, Err>
is the type used for returning and propagating errors. It is a type with the variants, #ok(Ok)
, representing success and containing a value, and #err(Err)
, representing error and containing an error value.
The simplest way of working with Result
s is to pattern match on them:
For example, given a function createUser(user : User) : Result<Id, String>
where String
is an error message we could use it like so:
switch(createUser(myUser)) {
case #ok(id) Debug.print("Created new user with id: " # id)
case #err(msg) Debug.print("Failed to create user with the error: " # msg)
}copy
equal
func equal<Ok, Err>(eqOk : (Ok, Ok) -> Bool, eqErr : (Err, Err) -> Bool, r1 : Result<Ok, Err>, r2 : Result<Ok, Err>) : Bool
compare
func compare<Ok, Err>(compareOk : (Ok, Ok) -> Order.Order, compareErr : (Err, Err) -> Order.Order, r1 : Result<Ok, Err>, r2 : Result<Ok, Err>) : Order.Order
chain
func chain<R1, R2, Error>(x : Result<R1, Error>, y : R1 -> Result<R2, Error>) : Result<R2, Error>
Allows sequencing of Result
values and functions that return `Result’s themselves.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Result "mo:base/Result";
type Result<T,E> = Result.Result<T, E>;
func largerThan10(x : Nat) : Result<Nat, Text> =
if (x > 10) { #ok(x) } else { #err("Not larger than 10.") };
func smallerThan20(x : Nat) : Result<Nat, Text> =
if (x < 20) { #ok(x) } else { #err("Not smaller than 20.") };
func between10And20(x : Nat) : Result<Nat, Text> =
Result.chain(largerThan10(x), smallerThan20);
assert(between10And20(15) == #ok(15));
assert(between10And20(9) == #err("Not larger than 10."));
assert(between10And20(21) == #err("Not smaller than 20."));
Run
flatten
func flatten<Ok, Error>(result : Result<Result<Ok, Error>, Error>) : Result<Ok, Error>
Flattens a nested Result.
1
2
3
4
import Result "mo:base/Result";
assert(Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10));
assert(Result.flatten<Nat, Text>(#err("Wrong")) == #err("Wrong"));
assert(Result.flatten<Nat, Text>(#ok(#err("Wrong"))) == #err("Wrong"));
Run
mapOk
func mapOk<Ok1, Ok2, Error>(x : Result<Ok1, Error>, f : Ok1 -> Ok2) : Result<Ok2, Error>
Maps the Ok
type/value, leaving any Error
type/value unchanged.
mapErr
func mapErr<Ok, Error1, Error2>(x : Result<Ok, Error1>, f : Error1 -> Error2) : Result<Ok, Error2>
Maps the Err
type/value, leaving any Ok
type/value unchanged.
fromOption
func fromOption<R, E>(x : ?R, err : E) : Result<R, E>
Create a result from an option, including an error value to handle the null
case.
import Result "mo:base/Result";
assert(Result.fromOption(?42, "err") == #ok(42));
assert(Result.fromOption(null, "err") == #err("err"));
Run
toOption
func toOption<R, E>(r : Result<R, E>) : ?R
Create an option from a result, turning all #err into null
.
import Result "mo:base/Result";
assert(Result.toOption(#ok(42)) == ?42);
assert(Result.toOption(#err("err")) == null);
Run
iterate
func iterate<Ok, Err>(res : Result<Ok, Err>, f : Ok -> ())
Applies a function to a successful value, but discards the result. Use iterate
if you’re only interested in the side effect f
produces.
1
2
3
4
5
6
import Result "mo:base/Result";
var counter : Nat = 0;
Result.iterate<Nat, Text>(#ok(5), func (x : Nat) { counter += x });
assert(counter == 5);
Result.iterate<Nat, Text>(#err("Wrong"), func (x : Nat) { counter += x });
assert(counter == 5);
Run
isOk
func isOk(r : Result<Any, Any>) : Bool
isErr
func isErr(r : Result<Any, Any>) : Bool
assertOk
func assertOk(r : Result<Any, Any>)
Asserts that its argument is an #ok
result, traps otherwise.
assertErr
func assertErr(r : Result<Any, Any>)
Asserts that its argument is an #err
result, traps otherwise.
Stack
Stack collection (LIFO discipline).
Minimal LIFO (last in first out) implementation, as a class. See library Deque
for mixed LIFO/FIFO behavior.
Stack
class Stack<T>()
push
func push(x : T)
Push an element on the top of the stack.
isEmpty
func isEmpty() : Bool
True when the stack is empty.
peek
func peek() : ?T
Return and retain the top element, or return null.
pop
func pop() : ?T
Remove and return the top element, or return null.
Text
Text values
This type represents human-readable text as sequences of characters of type Char
. If t
is a value of type Text
, then:
t.chars()
returns an iterator of typeIter<Char>
enumerating its characters from first to last.t.size()
returns the size (or length) oft
(andt.chars()
) as aNat
.t1 # t2
concatenates textst1
andt2
.
Represented as ropes of UTF-8 character sequences with O(1) concatenation.
This module defines additional operations on Text
values.
Text
type Text = Prim.Types.Text
Text values.
fromChar
let fromChar : (c : Char) -> Text
Conversion. Returns the text value of size 1 containing the single character c
.
toIter
func toIter(t : Text) : Iter.Iter<Char>
Conversion. Creates an iterator that traverses the characters of the text t
.
fromIter
func fromIter(cs : Iter.Iter<Char>) : Text
Conversion. Returns the text value containing the sequence of characters in cs
.
size
func size(t : Text) : Nat
Returns t.size()
, the number of characters in t
(and t.chars()
).
hash
func hash(t : Text) : Hash.Hash
Returns a hash obtained by using the djb2
algorithm from http://www.cse.yorku.ca/~oz/hash.html
This function is good enough for use in a hash-table but it’s not a cryptographic hash function!
concat
func concat(t1 : Text, t2 : Text) : Text
Returns the concatenation of t1
and t2
, t1 # t2
.
equal
func equal(t1 : Text, t2 : Text) : Bool
Returns t1 == t2
.
notEqual
func notEqual(t1 : Text, t2 : Text) : Bool
Returns t1 != t2
.
less
func less(t1 : Text, t2 : Text) : Bool
Returns t1 < t2
.
lessOrEqual
func lessOrEqual(t1 : Text, t2 : Text) : Bool
Returns t1 ⇐ t2
.
greater
func greater(t1 : Text, t2 : Text) : Bool
Returns t1 > t2
.
greaterOrEqual
func greaterOrEqual(t1 : Text, t2 : Text) : Bool
Returns t1 >= t2
.
compare
func compare(t1 : Text, t2 : Text) : {#less; #equal; #greater}
Returns the order of t1
and t1
.
join
func join(sep : Text, ts : Iter.Iter<Text>) : Text
Returns the concatenation of text values in ts
, separated by sep
.
map
func map(t : Text, f : Char -> Char) : Text
Returns the result of applying f
to each character in ts
, concatenating the intermediate single-character text values.
translate
func translate(t : Text, f : Char -> Text) : Text
Returns the result of applying f
to each character in ts
, concatenating the intermediate text values.
Pattern
type Pattern = {#char : Char; #text : Text; #predicate : (Char -> Bool)}
A pattern p
describes a sequence of characters. A pattern has one of the following forms:
#char c
matches the single character sequence,c
.#predicate p
matches any single character sequencec
satisfying predicatep(c)
.#text t
matches multi-character text sequencet
.
A match for p
is any sequence of characters matching the pattern p
.
split
func split(t : Text, p : Pattern) : Iter.Iter<Text>
Returns the sequence of fields in t
, derived from start to end, separated by text matching pattern p
. Two fields are separated by exactly one match.
tokens
func tokens(t : Text, p : Pattern) : Iter.Iter<Text>
Returns the sequence of tokens in t
, derived from start to end. A token is a non-empty maximal subsequence of t
not containing a match for pattern p
. Two tokens may be separated by one or more matches of p
.
contains
func contains(t : Text, p : Pattern) : Bool
Returns true if t
contains a match for pattern p
.
startsWith
func startsWith(t : Text, p : Pattern) : Bool
Returns true
if t
starts with a prefix matching pattern p
, otherwise returns false
.
endsWith
func endsWith(t : Text, p : Pattern) : Bool
Returns true
if t
ends with a suffix matching pattern p
, otherwise returns false
.
replace
func replace(t : Text, p : Pattern, r : Text) : Text
Returns t
with all matches of pattern p
replaced by text r
.
stripStart
func stripStart(t : Text, p : Pattern) : ?Text
Returns the optioned suffix of t
obtained by eliding exactly one leading match of pattern p
, otherwise null
.
stripEnd
func stripEnd(t : Text, p : Pattern) : ?Text
Returns the optioned prefix of t
obtained by eliding exactly one trailing match of pattern p
, otherwise null
.
trimStart
func trimStart(t : Text, p : Pattern) : Text
Returns the suffix of t
obtained by eliding all leading matches of pattern p
.
trimEnd
func trimEnd(t : Text, p : Pattern) : Text
Returns the prefix of t
obtained by eliding all trailing matches of pattern p
.
trim
func trim(t : Text, p : Pattern) : Text
Returns the subtext of t
obtained by eliding all leading and trailing matches of pattern p
.
compareWith
func compareWith(t1 : Text, t2 : Text, cmp : (Char, Char) -> {#less; #equal; #greater}) : {#less; #equal; #greater}
Returns the lexicographic comparison of t1
and t2
, using the given character ordering cmp
.
encodeUtf8
let encodeUtf8 : Text -> Blob
Returns the UTF-8 encoding of the given text
decodeUtf8
let decodeUtf8 : Blob -> ?Text
Tries to decode the given Blob
as UTF-8. Returns null
if the blob is not valid UTF-8.
Time
System time
Time
type Time = Int
System time is represent as nanoseconds since 1970-01-01.
now
let now : () -> Time
Current system time given as nanoseconds since 1970-01-01. The system guarantees that:
- the time, as observed by the canister, is monotonically increasing, even across canister upgrades.
- within an invocation of one entry point, the time is constant.
The system times of different canisters are unrelated, and calls from one canister to another may appear to travel “backwards in time”
Note: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.
Trie
Functional maps
Functional maps (and sets) whose representation is “canonical”, and independent of their operation history (unlike other popular search trees).
Background
The representation we use here comes from Section 6 of “Incremental computation via function caching”, Pugh & Teitelbaum.
Trie
type Trie<K, V> = {#empty; #leaf : Leaf<K, V>; #branch : Branch<K, V>}
binary hash tries: either empty, a leaf node, or a branch node
Leaf
type Leaf<K, V> = { size : Nat; keyvals : AssocList<Key<K>, V> }
leaf nodes of trie consist of key-value pairs as a list.
Branch
type Branch<K, V> = { size : Nat; left : Trie<K, V>; right : Trie<K, V> }
branch nodes of the trie discriminate on a bit position of the keys’ hashes. we never store this bitpos; rather, we enforce a style where this position is always known from context.
AssocList
type AssocList<K, V> = AssocList.AssocList<K, V>
Key
type Key<K> = { hash : Hash.Hash; key : K }
equalKey
func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool)
Equality function for two Key<K>
s, in terms of equality of `K’s.
isValid
func isValid<K, V>(t : Trie<K, V>, enforceNormal : Bool) : Bool
checks the invariants of the trie structure, including the placement of keys at trie paths
Trie2D
type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>
A 2D trie maps dimension-1 keys to another layer of tries, each keyed on the dimension-2 keys.
Trie3D
type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V>>
A 3D trie maps dimension-1 keys to another layer of 2D tries, each keyed on the dimension-2 and dimension-3 keys.
empty
func empty<K, V>() : Trie<K, V>
An empty trie.
size
func size<K, V>(t : Trie<K, V>) : Nat
Get the number of key-value pairs in the trie, in constant time.
branch
func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V>
Construct a branch node, computing the size stored there.
leaf
func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V>
Construct a leaf node, computing the size stored there.
This helper function automatically enforces the MAX_LEAF_SIZE by constructing branches as necessary; to do so, it also needs the bitpos of the leaf.
fromList
func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V>
clone
func clone<K, V>(t : Trie<K, V>) : Trie<K, V>
clone the trie efficiently, via sharing.
Purely-functional representation permits O(1) copy, via persistent sharing.
replace
func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V)
replace the given key’s value option with the given one, returning the previous one
put
func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V)
put the given key’s value in the trie; return the new trie, and the previous value associated with the key, if any
find
func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V
find the given key's value in the trie, or return null if nonexistent
merge
func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V>
merge tries, preferring the right trie where there are collisions
in common keys.
note: the `disj` operation generalizes this `merge`
operation in various ways, and does not (in general) lose
information; this operation is a simpler, special case.
See also:
disj
join
prod
mergeDisjoint
func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V>
like merge
, it merges tries, but unlike merge
, it signals a dynamic error if there are collisions in common keys between the left and right inputs.
diff
func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool) : Trie<K, V>
The key-value pairs of the final trie consists of those pairs of the left trie whose keys are not present in the right trie; the values of the right trie are irrelevant.
disj
func disj<K, V, W, X>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool, vbin : (?V, ?W) -> X) : Trie<K, X>
This operation generalizes the notion of “set union” to finite maps.
Produces a “disjunctive image” of the two tries, where the values of matching keys are combined with the given binary operator.
For unmatched key-value pairs, the operator is still applied to create the value in the image. To accomodate these various situations, the operator accepts optional values, but is never applied to (null, null).
Implements the database idea of an “outer join”.
See also:
join
merge
prod
join
func join<K, V, W, X>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool, vbin : (V, W) -> X) : Trie<K, X>
This operation generalizes the notion of “set intersection” to finite maps. Produces a “conjuctive image” of the two tries, where the values of matching keys are combined with the given binary operator, and unmatched key-value pairs are not present in the output.
Implements the database idea of an “inner join”.
See also:
disj
merge
prod
foldUp
func foldUp<K, V, X>(t : Trie<K, V>, bin : (X, X) -> X, leaf : (K, V) -> X, empty : X) : X
This operation gives a recursor for the internal structure of tries. Many common operations are instantiations of this function, either as clients, or as hand-specialized versions (e.g., see , map, mapFilter, some and all below).
prod
func prod<K1, V1, K2, V2, K3, V3>(tl : Trie<K1, V1>, tr : Trie<K2, V2>, op : (K1, V1, K2, V2) -> ?(Key<K3>, V3), k3_eq : (K3, K3) -> Bool) : Trie<K3, V3>
Conditional catesian product, where the given operation op
conditionally creates output elements in the resulting trie.
The keyed structure of the input tries are not relevant for this operation: all pairs are considered, regardless of keys matching or not. Moreover, the resulting trie may use keys that are unrelated to these input keys.
See also:
disj
join
merge
Build
let Build
Represent the construction of tries as data.
This module provides optimized variants of normal tries, for more efficient join queries.
The central insight is that for (unmaterialized) join query results, we do not need to actually build any resulting trie of the resulting data, but rather, just need a collection of what would be in that trie. Since query results can be large (quadratic in the DB size), avoiding the construction of this trie provides a considerable savings.
To get this savings, we use an ADT for the operations that would build this trie, if evaluated. This structure specializes a rope: a balanced tree representing a sequence. It is only as balanced as the tries from which we generate these build ASTs. They have no intrinsic balance properties of their own.
fold
func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X
Fold over the key-value pairs of the trie, using an accumulator. The key-value pairs have no reliable or meaningful ordering.
some
func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool
Test whether a given key-value pair is present, or not.
all
func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool
Test whether all key-value pairs have a given property.
nth
func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V)
Project the nth key-value pair from the trie.
Note: This position is not meaningful; it’s only here so that we can inject tries into arrays using functions like Array.tabulate
.
toArray
func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W]
Gather the collection of key-value pairs into an array of a (possibly-distinct) type.
Implementation notes:
we use this function repeatedly in the Produce Exchange example application, often on very large tries.
Performance Profiling shows that it is important that this be memory efficient, and reasonably time efficient, at large scales.
To do so, we use a single array allocation (for the returned array) and we sacrifice some efficiency in reading the input trie, and instead use function nth
to project each element with an independent trie traversal.
This approach is somewhat forced on us by the type signature of A.tabulate, and the desire to only allocate one array; that requirement rules out iterative mutation of an optionally-null array, since an imperative approach which would give us the wrong return type.
Since we want to statically rule out null output elements, and since the AS type system cannot do that for an imperative approach unless we assume more about the type W (e.g., the existence of “default values”), we settle for using nth
.
isEmpty
func isEmpty<K, V>(t : Trie<K, V>) : Bool
Test for “deep emptiness”: subtrees that have branching structure, but no leaves. These can result from naive filtering operations; filter uses this function to avoid creating such subtrees.
filter
func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V>
filter the key-value pairs by a given predicate.
mapFilter
func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W>
map and filter the key-value pairs by a given predicate.
equalStructure
func equalStructure<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, keq : (K, K) -> Bool, veq : (V, V) -> Bool) : Bool
Test for equality, but naively, based on structure. Does not attempt to remove “junk” in the tree; For instance, a “smarter” approach would equate #bin {left = #empty; right = #empty}
with #empty
. We do not observe that equality here.
replaceThen
func replaceThen<K, V, X>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v2 : V, success : (Trie<K, V>, V) -> X, fail : () -> X) : X
replace the given key’s value in the trie, and only if successful, do the success continuation, otherwise, return the failure value
putFresh
func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V>
put the given key’s value in the trie; return the new trie; assert that no prior value is associated with the key
put2D
func put2D<K1, K2, V>(t : Trie2D<K1, K2, V>, k1 : Key<K1>, k1_eq : (K1, K1) -> Bool, k2 : Key<K2>, k2_eq : (K2, K2) -> Bool, v : V) : Trie2D<K1, K2, V>
put the given key’s value in the 2D trie; return the new 2D trie.
put3D
func put3D<K1, K2, K3, V>(t : Trie3D<K1, K2, K3, V>, k1 : Key<K1>, k1_eq : (K1, K1) -> Bool, k2 : Key<K2>, k2_eq : (K2, K2) -> Bool, k3 : Key<K3>, k3_eq : (K3, K3) -> Bool, v : V) : Trie3D<K1, K2, K3, V>
put the given key’s value in the trie; return the new trie;
remove
func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V)
remove the given key’s value in the trie; return the new trie
removeThen
func removeThen<K, V, X>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, success : (Trie<K, V>, V) -> X, fail : () -> X) : X
remove the given key’s value in the trie, and only if successful, do the success continuation, otherwise, return the failure value
remove2D
func remove2D<K1, K2, V>(t : Trie2D<K1, K2, V>, k1 : Key<K1>, k1_eq : (K1, K1) -> Bool, k2 : Key<K2>, k2_eq : (K2, K2) -> Bool) : (Trie2D<K1, K2, V>, ?V)
remove the given key-key pair’s value in the 2D trie; return the new trie, and the prior value, if any.
remove3D
func remove3D<K1, K2, K3, V>(t : Trie3D<K1, K2, K3, V>, k1 : Key<K1>, k1_eq : (K1, K1) -> Bool, k2 : Key<K2>, k2_eq : (K2, K2) -> Bool, k3 : Key<K3>, k3_eq : (K3, K3) -> Bool) : (Trie3D<K1, K2, K3, V>, ?V)
remove the given key-key pair’s value in the 3D trie; return the new trie, and the prior value, if any.
mergeDisjoint2D
func mergeDisjoint2D<K1, K2, V>(t : Trie2D<K1, K2, V>, k1_eq : (K1, K1) -> Bool, k2_eq : (K2, K2) -> Bool) : Trie<K2, V>
Like mergeDisjoint
, except instead of merging a pair, it merges the collection of dimension-2 sub-trees of a 2D trie.
TrieMap
Functional map
This module defines an imperative hash map, with a general key and value type. It matches the interface and semantics of HashMap. Unlike HashMap, its internal representation uses a functional hash trie (see library Trie
).
This class permits us to compare the performance of two representations of hash-based maps, where tries (as binary trees) permit more efficient, constant-time, cloning compared with ordinary tables. This property is nice for supporting transactional workflows where map mutations may be provisional, and where we may expect some mutations to be uncommitted, or to “roll back”.
For now, this class does not permit a direct clone
operation (neither does HashMap
), but it does permit creating iterators via iter()
. The effect is similar: Each iterator costs O(1)
to create, but represents a fixed view of the mapping that does not interfere with mutations (it will not view subsequent insertions or mutations, if any).
TrieMap
class TrieMap<K, V>(isEq : (K, K) -> Bool, hashOf : K -> Hash.Hash)
size
func size() : Nat
Returns the number of entries in the map.
put
func put(k : K, v : V)
Associate a key and value, overwriting any prior association for the key.
replace
func replace(k : K, v : V) : ?V
Put the key and value, and return the (optional) prior value for the key.
get
func get(k : K) : ?V
Get the (optional) value associated with the given key.
delete
func delete(k : K)
Delete the (optional) value associated with the given key.
remove
func remove(k : K) : ?V
Delete and return the (optional) value associated with the given key.
entries
func entries() : I.Iter<(K, V)>
Returns an Iter
over the entries.
Each iterator gets a persistent view of the mapping, independent of concurrent updates to the iterated map.
clone
func clone<K, V>(h : TrieMap<K, V>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash) : TrieMap<K, V>
Clone the map, given its key operations.
fromEntries
func fromEntries<K, V>(entries : I.Iter<(K, V)>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash) : TrieMap<K, V>
Clone an iterator of key-value pairs.
map
func map<K, V1, V2>(h : TrieMap<K, V1>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash, mapFn : (K, V1) -> V2) : TrieMap<K, V2>
Transform (map) the values of a map, retaining its keys.
mapFilter
func mapFilter<K, V1, V2>(h : TrieMap<K, V1>, keyEq : (K, K) -> Bool, keyHash : K -> Hash.Hash, mapFn : (K, V1) -> ?V2) : TrieMap<K, V2>
Transform and filter the values of a map, retaining its keys.
TrieSet
Functional set
Sets are partial maps from element type to unit type, i.e., the partial map represents the set with its domain.
Hash
type Hash = Hash.Hash
Set
type Set<T> = Trie.Trie<T, ()>
empty
func empty<T>() : Set<T>
Empty set.
put
func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T>
Put an element into the set.
delete
func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T>
Delete an element from the set.
equal
func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool
Test if two sets are equal.
size
func size<T>(s : Set<T>) : Nat
The number of set elements, set’s cardinality.
mem
func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool
Test if a set contains a given element.
union
func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T>
diff
func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T>
intersect
func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T>
fromArray
func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T>
toArray
func toArray<T>(s : Set<T>) : [T]