Skip to content

The prelude

Every Emet module opens with these bindings already in scope; nothing imports them. They are total Rust functions seeded into the type and value environments emetc starts every module from — not library source. There is no prelude module to import, no bootstrap .emet file to ship, and no search path to resolve before a program can call List.map. Names carrying a List. / Maybe. / String. / Char. prefix are a dotted-name convention, not a module system — List.map is one identifier resolved by lookup.

Signatures use Emet type syntax: a/b are type variables, number / comparable / appendable are the three bounded variables, and -> is right-associative so Int -> Int -> Int is a two-argument function. The bounds, the infix operators, and the base types are defined in Values and types; this page lists the named functions and states each one’s behavior. For the four glyph constructors (aptPackage, file, …) see The four glyphs.

Basics

Numeric, comparison, and boolean functions Elm exposes without a module prefix, plus the constructors of the built-in sum types.

The arithmetic and comparison operators (+ - * / // ^ < > <= >= == /= && || ++ ::) desugar to applications of ordinary prelude builtins, so inference and evaluation see nothing but function application: a + b is add a b, a == b is eq a b, a ++ b is append a b, x :: xs is cons x xs.

OperatorBuiltinSignature
+ - * ^add sub mul pownumber -> number -> number
/fdivFloat -> Float -> Float
//idivInt -> Int -> Int
< > <= >=lt gt le gecomparable -> comparable -> Bool
== /=eq neqcomparable -> comparable -> Bool
&& ||and orBool -> Bool -> Bool
++appendappendable -> appendable -> appendable
::consa -> List a -> List a

Each desugaring target is a bound name, so add 1 2 and cons x xs compile and mean what the operator means. The operator is the idiomatic spelling; the name is what a partial application needs — List.map (add 1) xs.

Numeric

SignatureBehavior
abs : number -> numberabsolute value
negate : number -> numberarithmetic negation
clamp : number -> number -> number -> numberclamp lo hi x confines x to lo..=hi
toFloat : Int -> Floatwiden an Int to Float
round : Float -> Intround to the nearest integer
floor : Float -> Intround toward negative infinity
ceiling : Float -> Intround toward positive infinity
truncate : Float -> Intround toward zero
modBy : Int -> Int -> IntmodBy m x is x modulo m, sign of m; modBy 0 _ is 0
remainderBy : Int -> Int -> IntremainderBy d x is the remainder of x / d, sign of x; remainderBy 0 _ is 0
clamp 0 255 300 -- 255
modBy 3 10 -- 1

Integer division // and exponentiation ^ are the operators for idiv and pow — see Values and types. Division, modBy, and remainderBy are total: a zero divisor yields 0 rather than trapping.

Comparison

Operate on any comparable (Int, Float, String, Char, and orderings of them).

SignatureBehavior
compare : comparable -> comparable -> OrderLT, EQ, or GT
min : comparable -> comparable -> comparablethe lesser of two
max : comparable -> comparable -> comparablethe greater of two

The relational operators < > <= >= == /= yield Bool over the same comparable bound.

Boolean

SignatureBehavior
not : Bool -> Boollogical negation

&& and || are the operators for conjunction and disjunction.

Constructors

The built-in sum types are ordinary types defined by these constructors; they are in scope to build and to pattern-match.

ConstructorTypeMeaning
TrueBoolboolean true
FalseBoolboolean false
Justa -> Maybe aa present value
NothingMaybe aan absent value
LTOrderless-than, from compare
EQOrderequal
GTOrdergreater-than

String

The Elm elm/core String surface: names, argument order, and total / clamping semantics all follow Elm. Every length, index, and slice bound is a Unicode scalar index (String.length counts scalars), never a byte or grapheme offset — a combining mark counts as its own scalar. No function traps: out-of-range counts clamp and empty inputs return an empty result or [].

Building and converting

SignatureBehavior
String.append : String -> String -> Stringconcatenate two strings
String.concat : List String -> Stringconcatenate a list of strings
String.join : String -> List String -> Stringjoin sep parts inserts sep between parts
String.split : String -> String -> List Stringsplit sep s; an empty sep splits into one string per scalar
String.words : String -> List Stringsplit on runs of whitespace, trimming ends
String.lines : String -> List Stringsplit on \n, \r, and \r\n line terminators
String.repeat : Int -> String -> Stringrepeat n s is s concatenated n times
String.replace : String -> String -> String -> Stringreplace before after s replaces every before
String.cons : Char -> String -> Stringprepend a Char
String.fromChar : Char -> Stringa one-character string
String.fromInt : Int -> Stringdecimal rendering of an Int
String.fromFloat : Float -> Stringdecimal rendering of a Float
String.toInt : String -> Maybe Intparse an Int, else Nothing
String.toFloat : String -> Maybe Floatparse a Float, else Nothing
String.toList : String -> List Charthe string’s scalars, in order
String.fromList : List Char -> Stringassemble a string from scalars
String.uncons : String -> Maybe (Char, String)split off the first scalar: Just (first, rest), or Nothing on ""
String.join ", " [ "a", "b", "c" ] -- "a, b, c"
String.toInt "42" -- Just 42

Querying

SignatureBehavior
String.length : String -> Intnumber of Unicode scalars
String.isEmpty : String -> Boolwhether the string has no scalars
String.contains : String -> String -> Boolcontains needle s
String.startsWith : String -> String -> BoolstartsWith prefix s
String.endsWith : String -> String -> BoolendsWith suffix s
String.indexes : String -> String -> List Intscalar indices of every (possibly overlapping) match; empty needle → []
String.indices : String -> String -> List Intalias of String.indexes

Slicing

Every count is a scalar count; a count under 1 yields the empty string (or, for dropLeft / dropRight, the whole string).

SignatureBehavior
String.slice : Int -> Int -> String -> Stringslice start end s; negative indices count from the end, bounds clamp, crossed bounds → ""
String.left : Int -> String -> Stringfirst n scalars
String.right : Int -> String -> Stringlast n scalars
String.dropLeft : Int -> String -> Stringdrop the first n scalars
String.dropRight : Int -> String -> Stringdrop the last n scalars
String.slice 1 (-1) "hello" -- "ell"
String.right 3 "hello" -- "llo"

Case and whitespace

SignatureBehavior
String.reverse : String -> Stringreverse the scalars
String.toUpper : String -> Stringuppercase (full Unicode mapping)
String.toLower : String -> Stringlowercase (full Unicode mapping)
String.trim : String -> Stringstrip leading and trailing whitespace
String.trimLeft : String -> Stringstrip leading whitespace
String.trimRight : String -> Stringstrip trailing whitespace
String.pad : Int -> Char -> String -> Stringcenter-pad to width n; an odd deficit favors the left
String.padLeft : Int -> Char -> String -> Stringleft-pad to width n
String.padRight : Int -> Char -> String -> Stringright-pad to width n

Higher-order

SignatureBehavior
String.map : (Char -> Char) -> String -> Stringmap each scalar
String.filter : (Char -> Bool) -> String -> Stringkeep scalars passing the test
String.foldl : (Char -> b -> b) -> b -> String -> bfold from the left
String.foldr : (Char -> b -> b) -> b -> String -> bfold from the right
String.any : (Char -> Bool) -> String -> Boolwhether any scalar passes
String.all : (Char -> Bool) -> String -> Boolwhether every scalar passes

Char

The Elm elm/core Char surface. A Char is one Unicode scalar, agreeing with the scalar indexing of String above; it is authoring-time only and never reaches the wire. The is* predicates are Elm’s ASCII-oriented definitions.

SignatureBehavior
Char.toCode : Char -> Intthe Unicode code point
Char.fromCode : Int -> Charthe scalar for a code point; out-of-range or a surrogate → U+FFFD
Char.toUpper : Char -> Charuppercase mapping
Char.toLower : Char -> Charlowercase mapping
Char.isUpper : Char -> BoolASCII AZ
Char.isLower : Char -> BoolASCII az
Char.isAlpha : Char -> BoolASCII letter
Char.isAlphaNum : Char -> BoolASCII letter or digit
Char.isDigit : Char -> BoolASCII 09
Char.isOctDigit : Char -> BoolASCII 07
Char.isHexDigit : Char -> BoolASCII 09, af, AF
Char.isSpace : Char -> Boolspace, tab, newline, carriage return, vertical tab, or form feed
Char.toCode 'A' -- 65
Char.isDigit '7' -- True

List

The list combinators — Emet’s only way to iterate. List sum functions require number where they add.

SignatureBehavior
List.map : (a -> b) -> List a -> List bapply a function to each element
List.filter : (a -> Bool) -> List a -> List akeep elements passing the test
List.foldl : (a -> b -> b) -> b -> List a -> bfold from the left
List.foldr : (a -> b -> b) -> b -> List a -> bfold from the right
List.append : List a -> List a -> List aconcatenate two lists
List.concat : List (List a) -> List aflatten one level
List.concatMap : (a -> List b) -> List a -> List bmap then flatten
List.isEmpty : List a -> Boolwhether the list has no elements
List.length : List a -> Intnumber of elements
List.range : Int -> Int -> List Intrange lo hi is [lo..hi] inclusive; empty if lo > hi
List.sum : List number -> numbersum of the elements; []0
List.map (\x -> x * x) [ 1, 2, 3 ] -- [ 1, 4, 9 ]
List.foldl (\x acc -> acc + x) 0 [ 1, 2, 3 ] -- 6
List.range 1 5 -- [ 1, 2, 3, 4, 5 ]

Prepend an element with the :: operator; concatenate two lists (or two strings) with ++. Both desugar to the named builtins cons and append — see Values and types.

Maybe

SignatureBehavior
Maybe.map : (a -> b) -> Maybe a -> Maybe bmap the value inside a Just, else Nothing
Maybe.andThen : (a -> Maybe b) -> Maybe a -> Maybe bchain a Maybe-returning function
Maybe.withDefault : a -> Maybe a -> athe value in a Just, or the default for Nothing
Maybe.withDefault 0 (String.toInt "x") -- 0
Maybe.andThen (\n -> Just (n + 1)) (Just 4) -- Just 5

Tuple

Build and transform pairs. Every function operates on the two-element tuple — a three-element tuple is destructured by pattern, as in Elm. For the tuple type itself see Values and types.

SignatureBehavior
Tuple.pair : a -> b -> (a, b)build a pair from two values
Tuple.first : (a, b) -> athe first element
Tuple.second : (a, b) -> bthe second element
Tuple.mapFirst : (a -> x) -> (a, b) -> (x, b)apply a function to the first element
Tuple.mapSecond : (b -> y) -> (a, b) -> (a, y)apply a function to the second element
Tuple.mapBoth : (a -> x) -> (b -> y) -> (a, b) -> (x, y)apply a function to each element
Tuple.first (Tuple.pair 7 9) -- 7
Tuple.mapSecond (\n -> n + 1) (1, 2) -- (1, 3)

Secretspec

Resolve a secret declared in secretspec.toml. Unlike every other name on this page, this one runs at compile time: emetc reads the value from the configured provider and seals it into the manifest, so the result is a String the program can interpolate but the manifest never carries in the clear.

SignatureBehavior
Secretspec.get : String -> Stringthe value of a declared secret, sealed into the manifest
env "DB_PASSWORD" (Secretspec.get "DB_PASSWORD")

The key must be declared in secretspec.toml; an undeclared one is a compile error naming it and listing the declared keys, raised before any provider is consulted. A declared key the provider cannot supply is a separate error naming the provider.

Compiling a program that calls this needs provider access and the fleet key (--secret-key, or GOLEM_SECRET_KEY_FILE). A program that never calls it needs neither.

A sealed value may only be used where a value is expected. Reaching a path, a unit name, a scroll name, or a mode is a compile error, as is writing one through lineInFile. See Trust model for what sealing does and does not protect.