Built-In Definitions

/// Nat

dec Nat.Add   : [Nat, Nat] 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 : [type a] [Result<either {}, a>] a
def Result.Always = [type 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>,
}

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!),
  }


/// 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 : [type e] [Bytes.Reader<e>] String.Parser<e>


/// 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>,
  .writeString(String) => 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.Length  : [Bytes] Nat
dec Bytes.FromString : [String] Bytes

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.ReaderFromString : [String] Bytes.Reader<either {}>
dec Bytes.ParserFromReader : [type 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 {
  .stringName => String,
  .bytesName => Bytes,
  .stringAbsolute => String,
  .bytesAbsolute => Bytes,
  .stringParts => List<String>,
  .bytesParts => List<Bytes>,

  .parent => Option<self/parent>,
  .appendString(String) => self/append,
  .appendBytes(Bytes) => self/append,

  .openFile => Result<Os.Error, Os.Reader>,
  .createOrReplaceFile => Result<Os.Error, Os.Writer>,
  .createNewFile => Result<Os.Error, Os.Writer>,
  .appendToFile => Result<Os.Error, Os.Writer>,
  .createOrAppendToFile => Result<Os.Error, Os.Writer>,

  .listDir => Result<Os.Error, List<self/append>>,
  .traverseDir => Result<Os.Error, recursive/tree either {
    .end!,
    .file(self/append) self/tree,
    .dir(self/append, self/tree) self/tree,
  }>,
  .createDir => Result<Os.Error, !>,
}

dec Os.PathFromString : [String] Os.Path
dec Os.PathFromBytes  : [Bytes] Os.Path

dec Os.Stdin  : Os.Reader
dec Os.Stdout : Os.Writer


/// 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) String>)
  Bytes.Reader<Http.Error>

type Http.Response =
  (Nat)
  (List<(String) String>)
  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,
}

/// Map

type Map<k, v> = iterative choice {
  .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.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 {
  .list => List<(k) box v>,
  .get(k) => Option<box v>,
  .put(k, box v) => self,
  .delete(k) => self,
}

dec BoxMap.String : [type v] [List<(String) box v>] BoxMap<String, 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 : [type a] [a, dual Cell<a>] a


/// Debug

dec Debug.Log : [String] !