/// Nat
dec Nat.Add : [Nat, Nat] Nat
dec Nat.Sub : [Nat, Int] Nat
dec Nat.Mul : [Nat, Nat] Nat
dec Nat.Div : [Nat, Nat] Nat
dec Nat.Mod : [Nat, Nat] Nat
dec Nat.Min : [Nat, Nat] Nat
dec Nat.Max : [Nat, Int] Nat
dec Nat.Clamp : [Int] [Nat, Nat] Nat
dec Nat.Equals : [Nat, Nat] Bool
dec Nat.Compare : [Nat, Nat] Ordering
dec Nat.Repeat : [Nat] recursive either {
.end!,
.step self,
}
dec Nat.RepeatLazy : [Nat] recursive either {
.end!,
.step box choice {
.next => self,
}
}
dec Nat.Range : [Nat, Nat] List<Nat>
dec Nat.ToString : [Nat] String
dec Nat.FromString : [String] either {
.ok Nat,
.err!,
}
/// Int
dec Int.Add : [Int, Int] Int
dec Int.Sub : [Int, Int] Int
dec Int.Mul : [Int, Int] Int
dec Int.Div : [Int, Int] Int
dec Int.Mod : [Int, Nat] Nat
dec Int.Min : [Int, Int] Int
dec Int.Max : [Int, Int] Int
dec Int.Abs : [Int] Nat
dec Int.Clamp : [Int] [Int, Int] Int
dec Int.Equals : [Int, Int] Bool
dec Int.Compare : [Int, Int] Ordering
dec Int.Range : [Int, Int] List<Int>
dec Int.ToString : [Int] String
dec Int.FromString : [String] either {
.ok Int,
.err!,
}
/// Bool
type Bool = either {
.false!,
.true!,
}
/// Result
type Result<e, a> = either {
.ok a,
.err e,
}
dec Result.Always : <a>[Result<either {}, a>] a
def Result.Always = <a>[result] result.case {
.ok value => value,
.err impossible => impossible.case {},
}
type Option<a> = Result<!, a>
/// List
type List<a> = recursive either {
.end!,
.item(a) self,
}
type List.Builder<a> = iterative choice {
.add(a) => self,
.build => List<a>,
}
type List.Result<e, a> = recursive either {
.end Result<e, !>,
.item(a) self,
}
dec List.Builder : [type a] List.Builder<a>
def List.Builder = [type a]
let append: [List<a>] List<a> = [xs] xs
in begin case {
.add(x) => let append = [xs: List<a>] append(.item(x) xs) in loop,
.build => append(.end!),
}
dec List.Find : <a>[List<box a>] [box [box a] Bool] Option<a>
def List.Find = <a>[list] [f] list.begin.case {
.end! => .err!,
.item(v) list => f(v).case {
.true! => .ok v,
.false! => list.loop,
},
}
dec List.FindLast : <a>[List<box a>] [box [box a] Bool] Option<a>
def List.FindLast = <a>[list] [f]
let result: Option<box a> = .err! in
list.begin.case {
.end! => result,
.item(v) list => f(v).case {
.true! => let result = .ok v in list.loop,
.false! => list.loop,
},
}
dec List.Map : <a>[List<a>] [type b] [box [a] b] List<b>
def List.Map = <a>[list] [type b] [f] list.begin.case {
.end! => .end!
.item(v) list => .item(f(v)) list.loop,
}
dec List.FlatMap : <a>[List<a>] [type b] [box [a] List<b>] List<b>
def List.FlatMap = <a>[list] [type b] [f] list.begin.case {
.end! => .end!,
.item(v) list => f(v).begin@flat.case {
.end! => list.loop,
.item(v) flat => .item(v) flat.loop@flat,
},
}
dec List.Filter : <a>[List<box a>] [box [box a] Bool] List<a>
def List.Filter = <a>[list] [f] list.begin.case {
.end! => .end!,
.item(v) list => f(v).case {
.true! => .item(v) list.loop,
.false! => list.loop,
},
}
dec List.Fold : <a>[List<a>] <r>[r] [box [r, a] r] r
def List.Fold = <a>[list] <r>[result] [f] list.begin.case {
.end! => result,
.item(v) list => let result = f(result, v) in list.loop,
}
dec List.Reduce : <a>[List<a>] [box [a, a] a] Option<a>
def List.Reduce = <a>[list] [f] list.case {
.end! => .err!,
.item(result) list => .ok List.Fold(list, result, f),
}
dec List.Length : <a>[List<box a>] Nat
def List.Length = <a>[list]
let len = 0 in
list.begin.case {
.end! => len,
.item(_) list => do { len->Nat.Add(1) } in list.loop,
}
dec List.Concat : <a>[List<List<a>>] List<a>
def List.Concat = <a>[lists] chan yield {
lists.begin.case {
.item(list) => {
yield->List.Copy(list)
lists.loop
}
.end! => {
yield.end!
}
}
}
dec List.Copy : <a>[dual List<a>] [List<a>] dual List<a>
def List.Copy = <a>[dst] [src] do {
src.begin.case {
.end! => {},
.item(v) src => {
dst.item(v)
src.loop
},
}
} in dst
dec List.MinMax : <a>[List<box a>] [box [box a, box a] Ordering] Option<(a) a>
def List.MinMax = <a>[list] [cmp]
let result: Option<(box a) box a> = .err! in
list.begin.case {
.end! => result,
.item(v) list => result.case {
.err! =>
let result = .ok(v) v in
list.loop,
.ok(min) max =>
let result = cmp(v, min).case {
.less! => .ok (v) max,
else _ => cmp(v, max).case {
.greater! => .ok (min) v,
else _ => result,
},
} in list.loop,
},
}
dec List.Min : <a>[List<box a>] [box [box a, box a] Ordering] Option<a>
def List.Min = <a>[list] [cmp]
List.MinMax(list, cmp).case {
.err! => .err!,
.ok(min) _ => .ok min,
}
dec List.Max : <a>[List<box a>] [box [box a, box a] Ordering] Option<a>
def List.Max = <a>[list] [cmp]
List.MinMax(list, cmp).case {
.err! => .err!,
.ok(_) max => .ok max,
}
dec List.Zip : <a>[List<box a>] <b>[List<box b>] List<(a) b>
def List.Zip = <a>[list1] <b>[list2] chan yield {
list1.begin.case {
.end! => { yield.end! },
.item(v1) list1 => {
list2.case {
.end! => { yield.end! },
.item(v2) list2 => {
yield.item((v1) v2)
list1.loop
},
}
},
}
}
dec List.Unzip : <a, b>[List<(a) b>] (List<a>) List<b>
def List.Unzip = <a, b>[list] do {
let list1 = List.Builder(type a)
let list2 = List.Builder(type b)
list.begin.case {
.end! => {},
.item((v1) v2) list => {
list1.add(v1)
list2.add(v2)
list.loop
},
}
} in (list1.build) list2.build
dec List.All : <a>[List<box a>] [box [box a] Bool] Bool
def List.All = <a>[list] [f]
list.begin.case {
.end! => .true!,
.item(v) list => f(v).case {
.true! => list.loop,
.false! => .false!,
},
}
dec List.Any : <a>[List<box a>] [box [box a] Bool] Bool
def List.Any = <a>[list] [f] List.All(list, box [v] f(v).case {
.true! => .false!,
.false! => .true!,
})
dec List.Dedup : <a>[List<box a>] [box [box a, box a] Bool] List<a>
def List.Dedup = <a>[list] [eq]
list.case {
.end! => .end!,
.item(prev) list => .item(prev)
list.begin.case {
.end! => .end!,
.item(v) list => eq(prev, v).case {
.true! => list.loop,
.false! =>
let prev = v in
.item(v) list.loop,
}
}
}
dec List.Take : <a>[List<box a>] [Nat] List<a>
def List.Take = <a>[list] [n]
Nat.Repeat(n).begin.case {
.end! => .end!,
.step next => list.case {
.end! => .end!
.item(v) list => .item(v) next.loop,
}
}
dec List.Drop : <a>[List<box a>] [Nat] List<a>
def List.Drop = <a>[list] [n]
Nat.Repeat(n).begin.case {
.end! => list,
.step next => list.case {
.end! => .end!,
.item(_) list => next.loop,
},
}
dec List.Chunk : <a>[List<a>] [Nat] List<List<a>>
def List.Chunk = <a>[list] [n] chan outer {
let inner: Option<List.Builder<a>> = .err!
let i = 0
list.begin.case {
.end! => {
inner.case {
.err! => {},
.ok builder => { outer.item(builder.build) },
}
outer.end!
},
.item(v) list => {
inner.case {
.err! => {
let inner = .ok List.Builder(type a).add(v)
},
.ok builder => {
let inner = .ok builder.add(v)
},
}
i->Nat.Add(1)
Nat.Equals(i, n).case {
.true! => {
inner.case {
.ok builder => { outer.item(builder.build) },
}
let inner = .err!
let i = 0
list.loop
},
.false! => {
list.loop
},
}
},
}
}
/// Ordering
type Ordering = either {
.less!,
.equal!,
.greater!,
}
/// Char
type Char.Class = either {
.any!,
.char Char,
.whitespace!,
.ascii either {
.any!,
.alpha!,
.alphanum!,
.digit!,
},
}
dec Char.Equals : [Char, Char] Bool
dec Char.Code : [Char] Nat
dec Char.Is : [Char, Char.Class] Bool
/// String
type String.Builder = iterative choice {
.add(String) => self,
.build => String,
}
type String.Parser<e> = recursive iterative@attempt choice {
.close => Result<e, !>,
.remainder => Result<e, String>,
.char => either {
.end Result<e, !>,
.char(Char) self,
},
.match(String.Pattern, String.Pattern) => either {
.end Result<e, !>,
.fail self@attempt,
.match(String, String) self,
},
.matchEnd(String.Pattern, String.Pattern) => either {
.end Result<e, !>,
.fail self@attempt,
.match(String, String)!,
},
}
type String.Pattern = recursive either {
.empty!,
.str String,
.one Char.Class,
.non Char.Class,
.min Nat,
.max Nat,
.repeat self,
.repeat1 self,
.concat List<self>,
.and List<self>,
.or List<self>,
}
dec String.Quote : [String] String
dec String.FromBytes : [Bytes] String
dec String.Equals : [String, String] Bool
dec String.Compare : [String, String] Ordering
dec String.Builder : String.Builder
dec String.Parser : [String] String.Parser<either {}>
dec String.ParserFromReader : <e>[Bytes.Reader<e>] String.Parser<e>
dec String.Lines : <e>[String.Parser<e>] List.Result<e, String>
def String.Lines = <e>[parser]
catch e => .end .err e in
parser.begin.match(.repeat.one.any!, .str "\n").case {
.end try ! => .end .ok!,
.fail parser => let try r = parser.remainder in .item(r) .end .ok!,
.match(line, _) parser => .item(line) parser.loop,
}
dec String.Join : [List<String>, String] String
def String.Join = [list, sep]
let builder = String.Builder in
list.case {
.end! => builder.build,
.item(v) list => do {
builder.add(v)
} in list.begin.case {
.end! => builder.build,
.item(v) list => do {
builder.add(sep).add(v)
} in list.loop,
},
}
dec String.Concat : [List<String>] String
def String.Concat = [list]
let builder = String.Builder in
list.begin.case {
.end! => builder.build,
.item(v) list => do {
builder.add(v)
} in list.loop,
}
/// Byte
type Byte.Class = either {
.any!,
.byte Byte,
.range(Byte, Byte)!,
}
dec Byte.Equals : [Byte, Byte] Bool
dec Byte.Code : [Byte] Nat
dec Byte.Is : [Byte, Byte.Class] Bool
/// Bytes
type Bytes.Builder = iterative choice {
.add(Bytes) => self,
.build => Bytes,
}
type Bytes.Reader<e> = recursive choice {
.close => Result<e, !>,
.read => Result<e, either {
.end!,
.chunk(Bytes) self,
}>,
}
type Bytes.Writer<e> = iterative choice {
.close => Result<e, !>,
.flush => Result<e, self>,
.write(Bytes) => Result<e, self>,
}
type Bytes.Parser<e> = recursive iterative@attempt choice {
.close => Result<e, !>,
.remainder => Result<e, Bytes>,
.byte => either {
.end Result<e, !>,
.byte(Byte) self,
},
.match(Bytes.Pattern, Bytes.Pattern) => either {
.end Result<e, !>,
.fail self@attempt,
.match(Bytes, Bytes) self,
},
.matchEnd(Bytes.Pattern, Bytes.Pattern) => either {
.end Result<e, !>,
.fail self@attempt,
.match(Bytes, Bytes)!,
},
}
type Bytes.Pattern = recursive either {
.empty!,
.bytes Bytes,
.one Byte.Class,
.non Byte.Class,
.min Nat,
.max Nat,
.repeat self,
.repeat1 self,
.concat List<self>,
.and List<self>,
.or List<self>,
}
dec Bytes.Equals : [Bytes, Bytes] Bool
dec Bytes.Compare : [Bytes, Bytes] Ordering
dec Bytes.Length : [Bytes] Nat
dec Bytes.Builder : Bytes.Builder
dec Bytes.Reader : [Bytes] Bytes.Reader<either {}>
dec Bytes.Parser : [Bytes] Bytes.Parser<either {}>
dec Bytes.EmptyReader : Bytes.Reader<either {}>
dec Bytes.ParserFromReader : <e>[Bytes.Reader<e>] Bytes.Parser<e>
dec Bytes.PipeReader : [type e] [[Bytes.Writer<!>] Result<e, !>] Bytes.Reader<e>
/// Console
type Console = iterative choice {
.close => !,
.print(String) => self,
.prompt(String) => (Option<String>) self,
}
dec Console.Open : Console
/// Os
type Os.Error = String
type Os.Reader = Bytes.Reader<Os.Error>
type Os.Writer = Bytes.Writer<Os.Error>
type Os.Path = iterative@append recursive@parent box choice {
.name => Bytes,
.absolute => Bytes,
.parts => List<Bytes>,
.parent => Option<self@parent>,
.append(Bytes) => self@append,
}
dec Os.Path : [Bytes] Os.Path
dec Os.Stdin : Os.Reader
dec Os.Stdout : Os.Writer
dec Os.Stderr : Os.Writer
dec Os.OpenFile : [Os.Path] Result<Os.Error, Os.Reader>
dec Os.CreateOrReplaceFile : [Os.Path] Result<Os.Error, Os.Writer>
dec Os.CreateNewFile : [Os.Path] Result<Os.Error, Os.Writer>
dec Os.AppendToFile : [Os.Path] Result<Os.Error, Os.Writer>
dec Os.CreateOrAppendToFile : [Os.Path] Result<Os.Error, Os.Writer>
dec Os.CreateDir : [Os.Path] Result<Os.Error, !>
dec Os.ListDir : [Os.Path] Result<Os.Error, List<Os.Path>>
dec Os.TraverseDir : [Os.Path] Result<Os.Error, recursive either {
.end!,
.file(Os.Path) self,
.dir(Os.Path, self) self,
}>
dec Os.Env : BoxMap.Readonly<Bytes, Bytes>
/// Url
type Url.Error = String
type Url = iterative box choice {
.full => String,
.protocol => String,
.host => String,
.path => String,
.query => List<(String) String>,
.appendPath(String) => self,
.addQuery(String, String) => self,
}
dec Url.FromString : [String] Result<Url.Error, Url>
/// Http
type Http.Error = String
type Http.Request =
(String)
(Url)
(List<(String) Bytes>)
Bytes.Reader<Http.Error>
type Http.Response =
(Nat)
(List<(String) Bytes>)
Bytes.Reader<Http.Error>
dec Http.Fetch : [Http.Request] Result<Http.Error, Http.Response>
dec Http.Listen : [String] recursive either {
.shutdown Result<Http.Error, !>,
.incoming(Http.Request, [Http.Response] Result<Http.Error, !>) self,
}
/// Time
dec Time.Now : [!] Nat
/// Map
type Map<k, v> = iterative choice {
.size => (Nat) self,
.keys => (List<k>) self,
.list => List<(k) v>,
.entry(k) => (Option<v>) choice {
.put(v) => self,
.delete => self,
},
}
dec Map.String : [type v] [List<(String) box v>] Map<String, v>
dec Map.Bytes : [type v] [List<(Bytes) box v>] Map<Bytes, v>
dec Map.Int : [type v] [List<(Int) box v>] Map<Int, v>
dec Map.Nat : [type v] [List<(Nat) box v>] Map<Nat, v>
/// BoxMap
type BoxMap<k, v> = iterative box choice {
.size => Nat,
.keys => List<k>,
.list => List<(k) box v>,
.get(k) => Option<box v>,
.put(k, box v) => self,
.delete(k) => self,
}
type BoxMap.Readonly<k, v> = box choice {
.size => Nat,
.keys => List<k>,
.list => List<(k) box v>,
.get(k) => Option<box v>,
}
dec BoxMap.String : [type v] [List<(String) box v>] BoxMap<String, v>
dec BoxMap.Bytes : [type v] [List<(Bytes) box v>] BoxMap<Bytes, v>
dec BoxMap.Int : [type v] [List<(Int) box v>] BoxMap<Int, v>
dec BoxMap.Nat : [type v] [List<(Nat) box v>] BoxMap<Nat, v>
/// Cell
type Cell<a> = iterative choice {
.end => ?,
.split(dual self) => self,
.take => (a) choice {
.put(a) => self,
}
}
dec Cell.Share : <a>[a] [dual Cell<a>] a
/// Debug
dec Debug.Log : [String] !