/*---------------------------------------------------------------------------
  Copyright 2012-2016 Microsoft Corporation.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the file "license.txt" at the root of this distribution.
---------------------------------------------------------------------------*/

/* This module defines standard operations that are always available.

   Some types and operations are required to be defined for the compiler
   to work correctly (i.e. types like `:int` or `:list`)
*/
public module core

infixr 80  (^)
infixl 70  (*), (%), (/), cdiv, cmod
infixl 60  (+), (-)
infix  40  (!=), (==), (<=), (>=), (<), (>)
infixr 30  (&&)
infixr 20  (||)

// prefix     (!), (-)



extern include {
  js file "core-handlers-inline.js" // must come first due to dependencies
}

extern include {
  cs file "core-inline.cs"
  js file "core-inline.js"
}

extern include {
  cs file "core-handlers-inline.cs"
}

extern include {
  js file "core-string-inline.js"
}

extern include {
  js file "core-console-inline.js"
}

extern include {
  js file "../../contrib/biginteger.js"
}


// ----------------------------------------------------------------------------
// Core types
// ----------------------------------------------------------------------------

// An arbitrary precision signed integer.
type intstd/core/int: V

// A string is a sequence of unicode character points (`char`).
// The encoding of a string is internal and there
// is no constant-time indexing of characters in a string.
// Use the `:sslice` type for efficient matching and retrieving
// sub-strings from string.\
// See also the [``std/text/string``](std_text_string.html) module.
type stringstd/core/string: V

// A 64-bit IEEE 754 floating point value.
// See also `std/num/double` for more operations on `:double`s.
type doublestd/core/double: V

// An any type. Used for extern calls
type anystd/core/any: V

// A unicode character.
// Characters are unicode _codepoint_\/s.
// This is different from a unicode _grapheme_ which represents a single displayed
// symbol and can consists of multiple codepoints due to combining characters and marks.
// (see also the [``std/text/unicode``](std_text_unicode.html) module.)
type charstd/core/char: V


// ----------------------------------------------------------------------------
// Core effects
// ----------------------------------------------------------------------------

// The _total_ effect represents the absence of any effect.
type <std/core/(<>): E> :: E

// The effect constructor extends an effect with another effect.
type <std/core/(<|>): (X, E) -> E|> :: (X,E) -> E

// The exception effect: a partial function may raise an exception.
type exnstd/core/exn: X :: X

// The divergence effect: a divergent function may not terminate.
type divstd/core/div: X :: X

// NonDeterminism: a nonDeterministic function may return varying
// results even when called with the same input values.
type ndetstd/core/ndet: X :: X

// The alloc effect signifies a function may allocate in a heap `:h`
type allocstd/core/alloc: H -> X :: H -> X

// The read effect: signifies that a function may read from from heap `:h`.
type readstd/core/read: H -> X :: H -> X

// The write effect: signifies that a function may write to heap `:h`.
type writestd/core/write: H -> X :: H -> X

// The console effect signifies that a function may read or write to the console.
type consolestd/core/console: X :: X

// An alias for the empty effect.
alias totalstd/core/total: E = <std/core/(<>): E>

// An alias for pure effects: a pure function always returns the same result
// when called with the same arguments but may not terminate or raise an exception.
alias purestd/core/pure: E = <std/core/(<>): Eexnstd/core/exn: X,divstd/core/div: X>

// Stateful funs can manipulate heap `:h` using allocations, reads and writes.
alias ststd/core/st: H -> E<hh: H> = <std/core/(<>): Ereadstd/core/read: H -> X<hh: H>, writestd/core/write: H -> X<hh: H>, allocstd/core/alloc: H -> X<hh: H>>

// The `:global` heap is a special heap constant to denote the global shared heap
type globalstd/core/global: H :: H

// The `:global-scope` is a special type constant to denote the global scope
type global-scopestd/core/global-scope: S :: S

// The `:net` effect signifies a function may access the network
type netstd/core/net: X :: X

// The `:file` effect signifies a function may access the file system
type filestd/core/file: X :: X

// The `:ui` effect signifies a function may access the graphics system
type uistd/core/ui: X :: X

// The `:blocking` effect signifies that a function may block
type blockingstd/core/blocking: X :: X

// The `:io-total` effect is used for functions that perform arbitrary I/O operations, but are terminating without raising exceptions.
alias io-totalstd/core/io-total: E = <std/core/(<>): Endetstd/core/ndet: X,consolestd/core/console: X,netstd/core/net: X,filestd/core/file: X,uistd/core/ui: X,ststd/core/st: H -> E<globalstd/core/global: H>>

// The `:io-noexn` effect is used for functions that perform arbitrary I/O operations, but raise no exceptions
alias io-noexnstd/core/io-noexn: E = <std/core/(<>): Edivstd/core/div: X,io-totalstd/core/io-total: E>

// The `:io` effect is used for functions that perform arbitrary I/O operations.
alias iostd/core/io: E = <std/core/(<>): Eexnstd/core/exn: X,io-noexnstd/core/io-noexn: E>

// ----------------------------------------------------------------------------
// Injection
// ----------------------------------------------------------------------------

// Add the state effect to a function effect.
// extern inline inject-st : forall<a,b,h,e> ((a) -> e b) -> total ((a) -> <st<h>|e> b)   { inline "#1" }

// Add the state effect to a function effect.
extern inline inject-ststd/core/inject-st: forall<a,h,e> (() -> e a) -> total (() -> <st<h>|e> a) : forall<aa: V,hh: H,ee: E> (() -> ee: E aa: V) -> totalstd/core/total: E (() -> <ststd/core/st: H -> E<hh: H>|ee: E> aa: V)  { inline "#1" }


// ----------------------------------------------------------------------------
// Exceptions
// ----------------------------------------------------------------------------

// Exceptions
type exceptionstd/core/exception: V

type open exception-infostd/core/exception-info: V {
  Errorexception-info: exception-info
  Assertexception-info: exception-info
  Todoexception-info: exception-info
  Rangeexception-info: exception-info
  Finalizeexception-info: exception-info
  Patternexception-info: exception-info( locationlocation: string : stringstd/core/string: V, definitiondefinition: string : stringstd/core/string: V )
  Systemexception-info: exception-info( errnoerrno: string : stringstd/core/string: V )
  Internalexception-info: exception-info( namename: string : stringstd/core/string: V )
}

extern infostd/core/info: (exn : exception) -> exception-info( exnexn: exception : exceptionstd/core/exception: V ) : exception-infostd/core/exception-info: V {
  cs "Primitive.ExnInfo"
  js "exn_info"
}

extern stack-tracestd/core/stack-trace: (exn : exception) -> string( exnexn: exception : exceptionstd/core/exception: V ) : stringstd/core/string: V {
  cs "Primitive.ExnStackTrace"
  js "exn_stacktrace"
}

extern exceptionstd/core/exception: (message : string, info : exception-info) -> exception( messagemessage: string : stringstd/core/string: V, infoinfo: exception-info : exception-infostd/core/exception-info: V ) : exceptionstd/core/exception: V {
  cs "Primitive.ExnException"
  js "exn_exception"
}

extern throwstd/core/throw: forall<a> (exn : exception) -> exn a( exnexn: exception : exceptionstd/core/exception: V ) : exnstd/core/exn: X aa: V {
  cs "Primitive.Throw"
  js "exn_throw"
}

// Return the message associated with an exception
extern messagestd/core/message: (exn : exception) -> string( exnexn: exception : exceptionstd/core/exception: V ) : stringstd/core/string: V {
  cs "Primitive.ExnMessage"
  js "exn_message"
}

// Show the exception message and its stack trace.
fun showstd/core/show: (exn : exception) -> string( exnexn: exception : exceptionstd/core/exception: V ) : stringstd/core/string: V {
  exnexn: exception.stack-tracestd/core/stack-trace: (exn : exception) -> string
}

// Raise an exception with a specified message.
fun errorstd/core/error: forall<a> (message : string) -> exn a( messagemessage: string : stringstd/core/string: V ) : exnstd/core/exn: X aa: V {
  throwstd/core/throw.1: forall<a> (message : string, err : ?exception-info) -> exn a(messagemessage: string,Errorstd/core/Error: exception-info)
}

// Throw an exception
fun throwstd/core/throw.1: forall<a> (message : string, err : ?exception-info) -> exn a( messagemessage: string : stringstd/core/string: V, errerr: ?exception-info : exception-infostd/core/optional: V -> V = Errorstd/core/Error: exception-info) : exnstd/core/exn: X aa: V {
  throwstd/core/throw: forall<a> (exn : exception) -> exn a( exceptionstd/core/exception: (message : string, info : exception-info) -> exception(messagemessage: string,errerr: exception-info) )
}

// Raise a pattern match exception. This is function is used internally by the
// compiler to generate error messages on pattern match failures.
extern error-patternstd/core/error-pattern: forall<a> (location : string, definition : string) -> exn a(locationlocation: string : stringstd/core/string: V, definitiondefinition: string : stringstd/core/string: V) : exnstd/core/exn: X aa: V {
  // needs to be extern since the compiler generates calls and dependency resolution does not work on it
  cs "Primitive.ExnErrorPattern"
  js "exn_error_pattern"
}

// Execute a `hndler` no matter what exception was raised in `action`.
extern finallystd/core/finally: forall<e,a> (hndler : () -> e (), action : () -> e a) -> e a : forall<ee: E,aa: V> (hndler: () -> ee: E (std/core/(): V)std/core/(): V, action: () -> ee: E aa: V) -> ee: E aa: V  {
  cs inline "Eff.Op.HandleFinally<##2>(#2,#1)"
  js inline "$std_core._handle_finally(#2,#1)"
}

private extern initiallyxstd/core/initiallyx: forall<e,a> (init : () -> e (), action : () -> e a) -> e a : forall<ee: E,aa: V> (init: () -> ee: E (std/core/(): V)std/core/(): V, action: () -> ee: E aa: V) -> ee: E aa: V  {
  cs inline "Eff.Op.HandleFinally<##2>(#2,null,#1)"
  js inline "$std_core._handle_finally(#2,null,#1)"
}

fun initiallystd/core/initially: forall<a,e> (init : () -> e (), action : () -> e a) -> e a(initinit: () -> _21455 (): () -> ee: E (std/core/(): V)std/core/(): V, actionaction: () -> _21455 _21454: () -> ee: E aa: V) : ee: E aa: V {
  initinit: () -> _21455 ()()
  initiallyxstd/core/initiallyx: forall<e,a> (init : () -> e (), action : () -> e a) -> e a( initinit: () -> _21455 (), actionaction: () -> _21455 _21454 )
}

// Catch any exception raised in `action` and handle it.
// Use `on-exn` or `on-exit` when appropiate.
extern trystd/core/try: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a( actionaction: () -> <exn|_13067> _13066 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V, hndlhndl: (exception) -> _13067 _13066: exceptionstd/core/exception: V -> ee: E aa: V ) : ee: E aa: V {
  cs inline "Eff.Op.HandleCatch<##1>(#1,#2, false)"
  js inline "$std_core._handle_catch(#1, #2, false)"
}

private extern prim-try-somestd/core/prim-try-some: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> <exn|e> a) -> <exn|e> a( actionaction: () -> <exn|_6361> _6360 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V, hndlhndl: (exception) -> <exn|_6361> _6360: exceptionstd/core/exception: V -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V) : <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V {
  cs inline "Eff.Op.HandleCatch<##1>(#1,#2, false)"
  js inline "$std_core._handle_catch(#1, #2, false)"
}

// _Deprecated_; use `try` instead. Catch an exception raised by `throw` and handle it.
// Use `on-exn` or `on-exit` when appropiate.
fun catchstd/core/catch: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a( actionaction: () -> <exn|_14253> _14252 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V, hndlhndl: (exception) -> _14253 _14252: exceptionstd/core/exception: V -> ee: E aa: V) : ee: E aa: V {
  trystd/core/try: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a(actionaction: () -> <exn|_14253> _14252,hndlhndl: (exception) -> _14253 _14252)
}

// Set a `hndler` that is called only when an exception is raised in the `action` block.
fun on-exnstd/core/on-exn: forall<a,e> (hndler : (exception) -> <exn|e> (), action : () -> <exn|e> a) -> <exn|e> a( hndlerhndler: (exception) -> <exn|_23509> () : exceptionstd/core/exception: V -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> (std/core/(): V)std/core/(): V, actionaction: () -> <exn|_23509> _23508 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V ) : <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V {
  prim-try-somestd/core/prim-try-some: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> <exn|e> a) -> <exn|e> a( actionaction: () -> <exn|_23509> _23508, fun(exnexn: exception){ hndlerhndler: (exception) -> <exn|_23509> ()(exnexn: exception); throwstd/core/throw: forall<a> (exn : exception) -> exn a(exnexn: exception) })
}

// Set a `hndler` that is always called when the `action` finishes (either normally or with an exception).
fun on-exitstd/core/on-exit: forall<a,e> (hndler : () -> e (), action : () -> e a) -> e a( hndlerhndler: () -> _23494 () : () -> ee: E (std/core/(): V)std/core/(): V, actionaction: () -> _23494 _23493 : () -> ee: E aa: V ) : ee: E aa: V {
  finallystd/core/finally: forall<e,a> (hndler : () -> e (), action : () -> e a) -> e a(hndlerhndler: () -> _23494 (),actionaction: () -> _23494 _23493)
}


// A `:try` type represents a first-class exception result.
type trystd/core/try: V -> V<aa: V> {
  Exntry: try<_2724>( exceptionexception: exception : exceptionstd/core/exception: V )
  Oktry: try<_2736>( resultresult: 65 : aa: V )
}

// Transform an exception effect to a `:try` type.
fun trystd/core/try.1: forall<a,e> (action : () -> <exn|e> a) -> e try<a>( actionaction: () -> <exn|_13082> _13081 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V ) : ee: E trystd/core/try: V -> V<aa: V> {
  trystd/core/try: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a({ Okstd/core/Ok: forall<a> (result : a) -> try<a>(actionaction: () -> <exn|_13082> _13081()) },Exnstd/core/Exn: forall<a> (exception : exception) -> try<a>)
}

// Return a default value when an exception is raised
fun try-defaultstd/core/try-default: forall<a,e> (value : a, action : () -> <exn|e> a) -> e a( valuevalue: _25858 : aa: V , actionaction: () -> <exn|_25859> _25858 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V ) : ee: E aa: V {
  trystd/core/try: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a( actionaction: () -> <exn|_25859> _25858, fun(__(288,20): exception) { valuevalue: _25858 })
}

// Transform an `:try` type back to an `exn` effect.
fun untrystd/core/untry: forall<a> (ex : try<a>) -> exn a( exex: try<_26064> : trystd/core/try: V -> V<aa: V> ) : exnstd/core/exn: X aa: V {
  match(exex: try<_26064>) {
    Exnstd/core/Exn: forall<a> (exception : exception) -> try<a>(exnexn: exception) -> throwstd/core/throw: forall<a> (exn : exception) -> exn a(exnexn: exception)
    Okstd/core/Ok: forall<a> (result : a) -> try<a>(xx: _26064)    -> xx: _26064
  }
}

// Transform a `:try` type to a `:maybe` value.
fun maybestd/core/maybe: forall<a> (t : try<a>) -> maybe<exception>( tt: try<_22362> : trystd/core/try: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<exceptionstd/core/exception: V> {
    match(tt: try<_22362>) {
        Exnstd/core/Exn: forall<a> (exception : exception) -> try<a>(exnexn: exception) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(exnexn: exception)
        Okstd/core/Ok: forall<a> (result : a) -> try<a> -> Nothingstd/core/Nothing: forall<a> maybe<a>
    }
}
// ----------------------------------------------------------------------------
// Cancelation
// Internally implemented using an (uncatchable) exception
// ----------------------------------------------------------------------------

type extend exception-info {
  private con Cancelexception-info: exception-info
}

// Was this a cancelation exception?
fun cancel?std/core/cancel?.1: (exn : exception) -> bool( exnexn: exception : exceptionstd/core/exception: V ) {
  match(exnexn: exception.infostd/core/info: (exn : exception) -> exception-info) {
    Cancelstd/core/Cancel: exception-info -> Truestd/core/True: bool
    _      -> Falsestd/core/False: bool
  }
}

// Was this a finalization exception?
fun finalize?std/core/finalize?.1: (exn : exception) -> bool(exnexn: exception : exceptionstd/core/exception: V) {
    match(exnexn: exception.infostd/core/info: (exn : exception) -> exception-info) {
        Finalizestd/core/Finalize: exception-info -> Truestd/core/True: bool
        _ -> Falsestd/core/False: bool
    }
}

// _unsafe_. The cancelation exception. User code should never throw
// this exception as it cannot be caught (but it is respected by `finally` blocks).
// It is used internally to `finalize` effect handlers that do not resume.
fun unsafe-cancel-exnstd/core/unsafe-cancel-exn: () -> exception() : exceptionstd/core/exception: V {
  exceptionstd/core/exception: (message : string, info : exception-info) -> exception("computation is canceled",Cancelstd/core/Cancel: exception-info)
}

private extern prim-try-allstd/core/prim-try-all: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a( actionaction: () -> <exn|_6396> _6395 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V, hndlhndl: (exception) -> _6396 _6395: exceptionstd/core/exception: V -> ee: E aa: V ) : ee: E aa: V {
  cs inline "Eff.Op.HandleCatch<##1>(#1,#2,true)"
  js inline "$std_core._handle_catch(#1,#2,true)"
}

// _unsafe_. Catch any exception, including a possible cancelation.
// Unsafe to use in general as you must guarantee to later use `untry` to re-throw
// at least a cancelation exception.
fun unsafe-try-allstd/core/unsafe-try-all: forall<a,e> (action : () -> <exn|e> a) -> e try<a>( actionaction: () -> <exn|_26039> _26038 : () -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V) : ee: E trystd/core/try: V -> V<aa: V> {
  prim-try-allstd/core/prim-try-all: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a({Okstd/core/Ok: forall<a> (result : a) -> try<a>(actionaction: () -> <exn|_26039> _26038())},Exnstd/core/Exn: forall<a> (exception : exception) -> try<a>);
}



// ----------------------------------------------------------------------------
// Internal types
// ----------------------------------------------------------------------------

// Optional is used internally by the compiler to pass optional arguments.
// It is usually displayed as `:?a` for some type `:a`.
type optionalstd/core/optional: V -> V<aa: V> {
  // The `Optional` constructor is used when an optional argument is given.
  con Optionaloptional: ?_4686(valuevalue: 176:aa: V)
  // `None` is used when an optional argument is not provided.
  con Noneoptional: ?_4698
}


// ----------------------------------------------------------------------------
// Null is used for external interfaces
// ----------------------------------------------------------------------------

// Abstract type used for passing `null` values to external functions
type nullstd/core/null: V -> V<aa: V>

// Unsafe: transform any type to a `null` type; used internally by the compiler.
external ".null-any"(xx: _5381 : aa: V) : nullstd/core/null: V -> V<aa: V> {
  cs inline "#1"
  js inline "(#1==null ? null : #1)"  // undefined -> null
}

// Transform a `:maybe` type to a `:null` type (using `null` for `Nothing`).
external nullstd/core/null: forall<a> (x : maybe<a>) -> null<a>(xx: maybe<_22979> : maybestd/core/maybe: V -> V<aa: V>) : nullstd/core/null: V -> V<aa: V> {
  cs inline "(#1.tag_ == __std_core._maybe_Tag.Nothing ? default(##1) : #1.@value)"
  js inline "(#1==null ? null : #1.value)"
}

// Transform a `:null` type to a `:maybe` type. Note that it is not
// always the case that `id(x) == maybe(null(x))` (e.g. when `x = Just(Nothing)`).
external maybestd/core/maybe.1: forall<a> (n : null<a>) -> maybe<a>( nn: null<_22384> : nullstd/core/null: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<aa: V> {
  cs inline "(EqualityComparer<##1>.Default.Equals(#1,default(##1)) ? __std_core._maybe<##1>.Nothing_ : new __std_core._maybe<##1>(#1))"
  js inline "(#1==null ? $std_core.Nothing : $std_core.Just(#1))"
}

// Cast a integer that is zero to a null
fun nullstd/core/null.1: (i : int) -> null<int>( ii: int : intstd/core/int: V ) : nullstd/core/null: V -> V<intstd/core/int: V>  {
    ii: int.maybestd/core/maybe.7: (i : int) -> maybe<int>.nullstd/core/null: forall<a> (x : maybe<a>) -> null<a>
}

// Cast an empty string a null
fun nullstd/core/null.2: (s : string) -> null<string>( ss: string : stringstd/core/string: V ) : nullstd/core/null: V -> V<stringstd/core/string: V>  {
    ss: string.maybestd/core/maybe.8: (s : string) -> maybe<string>.nullstd/core/null: forall<a> (x : maybe<a>) -> null<a>
}

// Cast a boolean `False` to null
fun nullstd/core/null.3: (b : bool) -> null<()>( bb: bool : boolstd/core/bool: V ) : nullstd/core/null: V -> V<(std/core/(): V)std/core/(): V> {
    bb: bool.maybestd/core/maybe.6: (b : bool) -> maybe<()>.nullstd/core/null: forall<a> (x : maybe<a>) -> null<a>
}

val null-conststd/core/null-const: forall<a> null<a> : forall<aa: V> nullstd/core/null: V -> V<aa: V> = nullstd/core/null: forall<a> (x : maybe<a>) -> null<a>(Nothingstd/core/Nothing: forall<a> maybe<a>)



// ----------------------------------------------------------------------------
// Standard functions
// ----------------------------------------------------------------------------

// The identity function returns its argument unchanged.
fun idstd/core/id: forall<a> (x : a) -> a(xx: _5548) {
  xx: _5548;
}

// The `const` funs returns its first argument and ignores the second.
fun conststd/core/const: forall<a,b> (x : a, y : b) -> a(xx: _5805,yy: _5806) {
  xx: _5805;
}

// Apply a function `f` to a specified argument `x`.
fun applystd/core/apply: forall<a,b,e> (f : (a) -> e b, x : a) -> e b(ff: (_5705) -> _5706 _5707,xx: _5705) {
  ff: (_5705) -> _5706 _5707(xx: _5705);
}

// Compose two funs `f` and `g`.
fun ostd/core/o: forall<a,b,c,e> (f : (a) -> e b, g : (c) -> e a) -> ((x : c) -> e b)(ff: (_5538) -> _5535 _5536,gg: (_5534) -> _5535 _5538) {
  (fun(xx: _5534){ ff: (_5538) -> _5535 _5536(gg: (_5534) -> _5535 _5538(xx: _5534)) })
}

// The `ignore` function ignores its argument.
fun ignorestd/core/ignore: forall<a> (x : a) -> ()( xx: _6217 : aa: V ) : (std/core/(): V)std/core/(): V {
  (std/core/(): ())std/core/(): ()
}

// Return a 'constant' function that ignores its argument and always returns the same result
fun conststd/core/const.1: forall<a,b> (default : a) -> total ((x : b) -> a)( defaultdefault: _5811 : aa: V ) : totalstd/core/total: E (( x : bb: V ) -> astd/core/(<>): E) {
  (fun(__(442, 8): _5812){ defaultdefault: _5811 })
}


// ----------------------------------------------------------------------------
// Standard Data types
// ----------------------------------------------------------------------------

// The `:void` type is empty and has no constructors.
// See also the `:()` unit type and the `:bool` type.
type voidstd/core/void: V

// The type of booleans has two inhabitants: `True` and `False`.
type boolstd/core/bool: V {
  con Falsebool: bool
  con Truebool: bool
}


fun intstd/core/int.3: (b : bool) -> int( bb: bool : boolstd/core/bool: V ) : intstd/core/int: V  { if (bb: bool) then 1 else 0 }

fun mbintstd/core/mbint: (m : maybe<int>) -> int( mm: maybe<int> : maybestd/core/maybe: V -> V<intstd/core/int: V> ) : intstd/core/int: V {
  match(mm: maybe<int>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> 0
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(ii: int) -> ii: int
  }
}

// Convert an int to a boolean, using `False` for 0 and `True` otherwise.
fun boolstd/core/bool: (i : int) -> bool( ii: int : intstd/core/int: V ) : boolstd/core/bool: V { ii: int!=std/core/(!=).1: (int, int) -> bool0 }

// Convert a `:maybe` type to a boolean using `False` for `Nothing` and `True` for `Just`.
fun boolstd/core/bool.1: forall<a> (m : maybe<a>) -> bool( mm: maybe<_13996> : maybestd/core/maybe: V -> V<aa: V> ) : boolstd/core/bool: V {
  match(mm: maybe<_13996>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> Falsestd/core/False: bool
    _       -> Truestd/core/True: bool
  }
}

// Convert a string to a boolean, using `False` for the empty string and `True` otherwise.
fun boolstd/core/bool.2: (s : string) -> bool( ss: string : stringstd/core/string: V ) : boolstd/core/bool: V { ss: string!=std/core/(!=).3: (string, string) -> bool"" }

// The unit type `:()` is inhabited by just a single value, namely `()`.
// See also the `:void` type and the `:bool` type.
struct (std/core/(): V)std/core/(): V

// A pair of values `:a` and `:b`.
struct (std/core/(,): (V, V) -> V,)std/core/(,): (V, V) -> V<aa: V,bb: V>(fstfst: 51:aa: V,sndsnd: 52:bb: V)

// A triple of values.
struct (std/core/(,,): (V, V, V) -> V,,)std/core/(,,): (V, V, V) -> V<aa: V,bb: V,cc: V>(fstfst: 75:aa: V,sndsnd: 76:bb: V,thdthd: 77:cc: V)

// A quadruple of values.
struct (std/core/(,,,): (V, V, V, V) -> V,,,)std/core/(,,,): (V, V, V, V) -> V<aa: V,bb: V,cc: V,dd: V>(fstfst: 84:aa: V,sndsnd: 85:bb: V,thdthd: 86:cc: V,field4field4: 87:dd: V)

// A quintuple of values.
struct (std/core/(,,,,): (V, V, V, V, V) -> V,,,,)std/core/(,,,,): (V, V, V, V, V) -> V<aa: V,bb: V,cc: V,dd: V,ee: V>(fstfst: 95:aa: V,sndsnd: 96:bb: V,thdthd: 97:cc: V,field4field4: 98:dd: V,field5field5: 99:ee: V)

// The `:maybe` type is used to represent either a value (`Just(x)`) or `Nothing`.
// This type is often used to represent values that can be _null_.
type maybestd/core/maybe: V -> V<aa: V> {
  con Nothingmaybe: maybe<_4663>
  con Justmaybe: maybe<_4674>( valuevalue: 168 : aa: V )
}

// Match a `:maybe` value and either return a default value on `Nothing` or apply a function to the value on `Just`
fun maybestd/core/maybe.2: forall<a,b,e> (m : maybe<a>, onNothing : b, onJust : (a) -> e b) -> e b( mm: maybe<_22407> : maybestd/core/maybe: V -> V<aa: V>, onNothingonNothing: _22408: bb: V, onJustonJust: (_22407) -> _22409 _22408: aa: V -> ee: E bb: V ) : ee: E bb: V
{
  match(mm: maybe<_22407>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> onNothingonNothing: _22408
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _22407) -> onJustonJust: (_22407) -> _22409 _22408(xx: _22407)
  }
}

// Convert a `:maybe<a>` value to `:a`, using the `nothing` parameter for `Nothing`.
// This is an alias for `default`.
fun maybestd/core/maybe.3: forall<a> (m : maybe<a>, nothing : a) -> a( mm: maybe<_22460> : maybestd/core/maybe: V -> V<aa: V>, nothingnothing: _22460 : aa: V ) : astd/core/(<>): E {
  defaultstd/core/default: forall<a> (m : maybe<a>, nothing : a) -> a(mm: maybe<_22460>,nothingnothing: _22460)
}

// Convert a `:maybe<a>` value to `:a`, using the `nothing` parameter for `Nothing`.
fun defaultstd/core/default: forall<a> (m : maybe<a>, nothing : a) -> a( mm: maybe<_5857> : maybestd/core/maybe: V -> V<aa: V>, nothingnothing: _5857 : aa: V ) : astd/core/(<>): E {
  match(mm: maybe<_5857>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> nothingnothing: _5857
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _5857) -> xx: _5857
  }
}

// Get the value of the `Just` constructor or raise an exception
fun unjuststd/core/unjust: forall<a> (m : maybe<a>) -> exn a( mm: maybe<_6780> : maybestd/core/maybe: V -> V<aa: V> ) : exnstd/core/exn: X aa: V {
  match(mm: maybe<_6780>) {
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _6780) -> xx: _6780
  }
}

fun mapstd/core/map: forall<a,b,e> (m : maybe<a>, f : (a) -> e b) -> e maybe<b>( mm: maybe<_10476> : maybestd/core/maybe: V -> V<aa: V>, ff: (_10476) -> _10478 _10477 : aa: V -> ee: E bb: V ) : ee: E maybestd/core/maybe: V -> V<bb: V> {
  match(mm: maybe<_10476>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> Nothingstd/core/Nothing: forall<a> maybe<a>
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _10476) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(ff: (_10476) -> _10478 _10477(xx: _10476))
  }
}

fun (||)std/core/(||).1: forall<a> (m1 : maybe<a>, m2 : maybe<a>) -> maybe<a>( m1m1: maybe<_9460> : maybestd/core/maybe: V -> V<aa: V>, m2m2: maybe<_9460>: maybestd/core/maybe: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<aa: V> {
  match(m1m1: maybe<_9460>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> m2m2: maybe<_9460>
    _       -> m1m1: maybe<_9460>
  }
}

// The choice type represents one of two possible types `:a` or `:b`.
type eitherstd/core/either: (V, V) -> V<aa: V,bb: V> {
  con Lefteither: either<_4409,_4410>( leftleft: 109 : aa: V )
  con Righteither: either<_4422,_4423>( rightright: 110 : bb: V )
}

// Convert a `:either` to a `:maybe` type discarding the value of the `Left` constructor
// and using `Just` for the `Right` constructor.
fun maybestd/core/maybe.4: forall<a,b> (e : either<a,b>) -> maybe<b>( ee: either<_22500,_22501> : eitherstd/core/either: (V, V) -> V<aa: V,bb: V> ) : maybestd/core/maybe: V -> V<bb: V>
{
  match(ee: either<_22500,_22501>) {
    Leftstd/core/Left: forall<a,b> (left : a) -> either<a,b> -> Nothingstd/core/Nothing: forall<a> maybe<a>
    Rightstd/core/Right: forall<a,b> (right : b) -> either<a,b>(xx: _22501) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _22501)
  }
}

// Map over the `Right` component of an `:either` type.
fun mapstd/core/map.1: forall<a,b,c,e> (e : either<a,b>, f : (b) -> e c) -> e either<a,c>( ee: either<_10504,_10505> : eitherstd/core/either: (V, V) -> V<aa: V,bb: V>, ff: (_10505) -> _10507 _10506 : bb: V -> ee: E cc: V  ) : ee: E eitherstd/core/either: (V, V) -> V<aa: V,cc: V> {
  match(ee: either<_10504,_10505>) {
    Rightstd/core/Right: forall<a,b> (right : b) -> either<a,b>(xx: _10505) -> Rightstd/core/Right: forall<a,b> (right : b) -> either<a,b>(ff: (_10505) -> _10507 _10506(xx: _10505))
    Leftstd/core/Left: forall<a,b> (left : a) -> either<a,b>(xx: _10504)  -> Leftstd/core/Left: forall<a,b> (left : a) -> either<a,b>(xx: _10504)
  }
}

// The type of lists, which can be either empty (`Nil`) or an element followed
// by a list (`Cons`).
type liststd/core/list: V -> V<aa: V> {
  // The empty list.
  con Nillist: list<_4640>
  // A ``head``  element followed by the ``tail``  of the list.
  con Conslist: list<_4651>(headhead: 159:aa: V, tailtail: list<159> : liststd/core/list: V -> V<aa: V> )
}

// Return the head of list if the list is not empty.
fun headstd/core/head.1: forall<a> (xs : list<a>) -> maybe<a>( xsxs: list<_20961> : liststd/core/list: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<aa: V> {
  match(xsxs: list<_20961>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _20961) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _20961)
    _       -> Nothingstd/core/Nothing: forall<a> maybe<a>
  }
}

// Return the head of list if the list is not empty, or use `default` otherwise
fun headstd/core/head.2: forall<a> (xs : list<a>, default : a) -> a( xsxs: list<_20992> : liststd/core/list: V -> V<aa: V>, defaultdefault: _20992 : aa: V ) : astd/core/(<>): E {
  match(xsxs: list<_20992>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _20992) -> xx: _20992
    _       -> defaultdefault: _20992
  }
}

// Return the tail of list. Returns the empty list if `xs` is empty.
fun tailstd/core/tail.1: forall<a> (xs : list<a>) -> list<a>( xsxs: list<_25471> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V> {
  match(xsxs: list<_25471>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(_,xxxx: list<_25471>) -> xxxx: list<_25471>
    _          -> [std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>
  }
}


// A `:stream` is a co-inductive type reprenting an infinite list of elements.
cotype streamstd/core/stream: V -> V<aa: V> {
  con Nextstd/core/Next: forall<a> (head : a, tail : stream<a>) -> stream<a>(headhead: 210:aa: V, tailtail: stream<210>: streamstd/core/stream: V -> V<aa: V> )
}

// An enumeration to represent order
type orderstd/core/order: V {
  Ltorder: order
  Eqorder: order
  Gtorder: order
}

fun intstd/core/int.4: (x : order) -> int( xx: order : orderstd/core/order: V ) : intstd/core/int: V
{
  match(xx: order) {
    Ltstd/core/Lt: order -> 0 -std/core/(-): (int, int) -> int 1
    Eqstd/core/Eq: order -> 0
    Gtstd/core/Gt: order -> 1
  }
}

fun orderstd/core/order: (i : int) -> order( ii: int : intstd/core/int: V ) : orderstd/core/order: V
{
  if (istd/core/True: bool <std/core/(<).1: (int, int) -> bool 0) Ltstd/core/Lt: order
  elif (istd/core/True: bool >std/core/(>).1: (int, int) -> bool 0) Gtstd/core/Gt: order
  else Eqstd/core/Eq: order
}

fun (==)std/core/(==).4: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V { xx: order.intstd/core/int.4: (x : order) -> int ==std/core/(==).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }
fun (!=)std/core/(!=).4: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V { xx: order.intstd/core/int.4: (x : order) -> int !=std/core/(!=).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }
fun (>=)std/core/(>=).3: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V { xx: order.intstd/core/int.4: (x : order) -> int >=std/core/(>=).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }
fun (<=)std/core/(<=).4: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V { xx: order.intstd/core/int.4: (x : order) -> int <=std/core/(<=).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }
fun (>)std/core/(>).3: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V  { xx: order.intstd/core/int.4: (x : order) -> int >std/core/(>).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }
fun (<)std/core/(<).4: (x : order, y : order) -> bool( xx: order : orderstd/core/order: V, yy: order : orderstd/core/order: V ) : boolstd/core/bool: V  { xx: order.intstd/core/int.4: (x : order) -> int <std/core/(<).1: (int, int) -> bool yy: order.intstd/core/int.4: (x : order) -> int }

fun mapstd/core/map.2: forall<a,b,e> (t : (a, a), f : (a) -> e b) -> e (b, b)( tt: (_10543, _10543) : (std/core/(,): (V, V) -> Vaa: V,aa: V)std/core/(,): (V, V) -> V, ff: (_10543) -> _10545 _10544 : aa: V -> ee: E bb: V ) : ee: E (std/core/(,): (V, V) -> Vbb: V, bb: V)std/core/(,): (V, V) -> V {
  (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)tt: (_10543, _10543).fststd/core/fst: forall<a,b> ((a, b)) -> a.ff: (_10543) -> _10545 _10544, tt: (_10543, _10543).sndstd/core/snd: forall<a,b> ((a, b)) -> b.ff: (_10543) -> _10545 _10544)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
}

fun mapstd/core/map.3: forall<a,b,e> (t : (a, a, a), f : (a) -> e b) -> e (b, b, b)( tt: (_10705, _10705, _10705) : (std/core/(,,): (V, V, V) -> Vaa: V,aa: V,aa: V)std/core/(,,): (V, V, V) -> V, ff: (_10705) -> _10707 _10706 : aa: V -> ee: E bb: V ) : ee: E (std/core/(,,): (V, V, V) -> Vbb: V, bb: V, bb: V)std/core/(,,): (V, V, V) -> V {
  (std/core/(,,): forall<a,b,c> (fst : a, snd : b, thd : c) -> (a, b, c)tt: (_10705, _10705, _10705).fststd/core/fst.1: forall<a,b,c> ((a, b, c)) -> a.ff: (_10705) -> _10707 _10706, tt: (_10705, _10705, _10705).sndstd/core/snd.1: forall<a,b,c> ((a, b, c)) -> b.ff: (_10705) -> _10707 _10706, tt: (_10705, _10705, _10705).thdstd/core/thd: forall<a,b,c> ((a, b, c)) -> c.ff: (_10705) -> _10707 _10706)std/core/(,,): forall<a,b,c> (fst : a, snd : b, thd : c) -> (a, b, c)
}

fun mapstd/core/map.4: forall<a,b,e> (t : (a, a, a, a), f : (a) -> e b) -> e (b, b, b, b)( tt: (_10946, _10946, _10946, _10946) : (std/core/(,,,): (V, V, V, V) -> Vaa: V,aa: V,aa: V,aa: V)std/core/(,,,): (V, V, V, V) -> V, ff: (_10946) -> _10948 _10947 : aa: V -> ee: E bb: V ) : ee: E (std/core/(,,,): (V, V, V, V) -> Vbb: V,bb: V,bb: V,bb: V)std/core/(,,,): (V, V, V, V) -> V {
  (std/core/(,,,): forall<a,b,c,d> (fst : a, snd : b, thd : c, field4 : d) -> (a, b, c, d)tt: (_10946, _10946, _10946, _10946).fststd/core/fst.2: forall<a,b,c,d> ((a, b, c, d)) -> a.ff: (_10946) -> _10948 _10947, tt: (_10946, _10946, _10946, _10946).sndstd/core/snd.2: forall<a,b,c,d> ((a, b, c, d)) -> b.ff: (_10946) -> _10948 _10947, tt: (_10946, _10946, _10946, _10946).thdstd/core/thd.1: forall<a,b,c,d> ((a, b, c, d)) -> c.ff: (_10946) -> _10948 _10947, tt: (_10946, _10946, _10946, _10946).field4std/core/field4: forall<a,b,c,d> ((a, b, c, d)) -> d.ff: (_10946) -> _10948 _10947)std/core/(,,,): forall<a,b,c,d> (fst : a, snd : b, thd : c, field4 : d) -> (a, b, c, d)
}

// ----------------------------------------------------------------------------
// List funs
// ----------------------------------------------------------------------------

// Returns a singleton list.
fun singlestd/core/single: forall<a> (x : a) -> list<a>(xx: _6744) {
  returnreturn: list<_6744> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _6744,Nilstd/core/Nil: forall<a> list<a>)
}

// Returns the length of a list.
fun lengthstd/core/length.1: forall<a> (xs : list<a>) -> int(xsxs: list<_10005>)
{
  fun lenlen: forall<a> (int, list<a>) -> int(accacc: int,ysys: list<_9955>) {
    match(ysys: list<_9955>)
    {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(_,yyyy: list<_9955>) -> lenlen: (int, list<_9955>) -> _9952 int( accacc: int+std/core/(+): (int, int) -> int1, yyyy: list<_9955> )
      Nilstd/core/Nil: forall<a> list<a>        -> accacc: int
    }
  }

  returnreturn: int lenlen: forall<a> (int, list<a>) -> int(0,xsxs: list<_10005>)
}

// Returns an integer list of increasing elements from `lo`  to `hi`
// (including both `lo`  and `hi` ).
// If `lo > hi`  the function returns the empty list.
fun liststd/core/list: (lo : int, hi : int) -> total list<int>( lolo: int: intstd/core/int: V, hihi: int: intstd/core/int: V ) : totalstd/core/total: E liststd/core/list: V -> V<intstd/core/int: V>
{
  fun enumerateenumerate: (low : int, high : int, acc : list<int>) -> list<int>( lowlow: int:intstd/core/int: V, highhigh: int:intstd/core/int: V, accacc: list<int>: liststd/core/list: V -> V<intstd/core/int: V> ) : liststd/core/list: V -> V<intstd/core/int: V>
  {
    if (lowstd/core/True: bool >std/core/(>).1: (int, int) -> bool highhigh: int)
     then accacc: list<int>
     else enumerateenumerate: (low : int, high : int, acc : list<int>) -> list<int>(lowlow: int, unsafe-decreasingstd/core/unsafe-decreasing: forall<a> (x : a) -> a(highhigh: int -std/core/(-): (int, int) -> int 1), Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(highhigh: int,accacc: list<int>))
  }

  enumerateenumerate: (low : int, high : int, acc : list<int>) -> list<int>(lolo: int,hihi: int,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>)
}

// Applies a function `f` to list of increasing elements from `lo`  to `hi`
// (including both `lo`  and `hi` ).
// If `lo > hi`  the function returns the empty list.
fun liststd/core/list.1: forall<a,e> (lo : int, hi : int, f : (int) -> e a) -> e list<a>( lolo: int : intstd/core/int: V, hihi: int: intstd/core/int: V, ff: (int) -> _1729 _11771 : intstd/core/int: V -> ee: E aa: V) : ee: E liststd/core/list: V -> V<aa: V> {
  fun enumerateenumerate: (low : int, high : int, acc : list<_11771>) -> _1729 list<_11771>( lowlow: int:intstd/core/int: V, highhigh: int:intstd/core/int: V, accacc: list<_11771> )
  {
    if (lowstd/core/True: bool >std/core/(>).1: (int, int) -> bool highhigh: int)
     then accacc: list<_11771>
     else enumerateenumerate: (low : int, high : int, acc : list<_11771>) -> _1729 list<_11771>(lowlow: int, unsafe-decreasingstd/core/unsafe-decreasing: forall<a> (x : a) -> a(highhigh: int -std/core/(-): (int, int) -> int 1), Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(ff: (int) -> _1729 _11771(highhigh: int),accacc: list<_11771>))
  }
  enumerateenumerate: (low : int, high : int, acc : list<_11771>) -> _1729 list<_11771>(lolo: int,hihi: int,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>)
}


// Create a list of characters from `lo`  to `hi`  (inclusive).
fun liststd/core/list.2: (lo : char, hi : char) -> total list<char>( lolo: char : charstd/core/char: V, hihi: char : charstd/core/char: V ) : totalstd/core/total: E liststd/core/list: V -> V<charstd/core/char: V>
{
  liststd/core/list: (lo : int, hi : int) -> total list<int>(lolo: char.intstd/core/int: (char) -> int, hihi: char.intstd/core/int: (char) -> int).mapstd/core/map.5: forall<a,b,e> (xs : list<a>, f : (a) -> e b) -> e list<b>( charstd/core/char: (int) -> char )
}

private val maxListStackstd/core/maxListStack: int = 100


private fun zipwith-accstd/core/zipwith-acc: forall<a,b,c,e> ((int, a, b) -> e c, int, list<c>, list<a>, list<b>) -> e list<c>( ff: (int, _13154, _13164) -> _13151 _13156, ii: int, accacc: list<_13156>, xsxs: list<_13154>, ysys: list<_13164> )
{
  match(xsxs: list<_13154>) {
    Nilstd/core/Nil: forall<a> list<a> -> reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(accacc: list<_13156>)
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _13154,xxxx: list<_13154>) ->
      match(ysys: list<_13164>) {
        Nilstd/core/Nil: forall<a> list<a> -> reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(accacc: list<_13156>)
        Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _13164,yyyy: list<_13164>) -> zipwith-accstd/core/zipwith-acc: ((int, _13154, _13164) -> _13151 _13156, int, list<_13156>, list<_13154>, list<_13164>) -> _13151 list<_13156>(ff: (int, _13154, _13164) -> _13151 _13156, ii: int+std/core/(+): (int, int) -> int1, Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>( ff: (int, _13154, _13164) -> _13151 _13156(ii: int,xx: _13154,yy: _13164), accacc: list<_13156>), xxxx: list<_13154>, yyyy: list<_13164>)
      }
  }
}

private fun zipwith-iterstd/core/zipwith-iter: forall<a,b,c,e> ((int, a, b) -> e c, int, list<a>, list<b>) -> e list<c>( ff: (int, _13276, _13277) -> _13241 _13278, ii: int, xsxs: list<_13276>, ysys: list<_13277> )
{
  // recurse for the first `maxListStack` elements over the stack (to avoid extra heap allocation)
  if (istd/core/True: bool >std/core/(>).1: (int, int) -> bool maxListStackstd/core/maxListStack: int) then zipwith-accstd/core/zipwith-acc: forall<a,b,c,e> ((int, a, b) -> e c, int, list<c>, list<a>, list<b>) -> e list<c>( ff: (int, _13276, _13277) -> _13241 _13278, ii: int, Nilstd/core/Nil: forall<a> list<a>, xsxs: list<_13276>, ysys: list<_13277> )
  else {
    match(xsxs: list<_13276>) {
      Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _13276,xxxx: list<_13276>) ->
        match(ysys: list<_13277>) {
          Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
          Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _13277,yyyy: list<_13277>) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>( ff: (int, _13276, _13277) -> _13241 _13278(ii: int,xx: _13276,yy: _13277), zipwith-iterstd/core/zipwith-iter: ((int, _13276, _13277) -> _13241 _13278, int, list<_13276>, list<_13277>) -> _13241 list<_13278>(ff: (int, _13276, _13277) -> _13241 _13278,ii: int+std/core/(+): (int, int) -> int1,xxxx: list<_13276>,yyyy: list<_13277>))
        }
    }
  }
}

// Zip two lists together by pairing the corresponding elements.
// The returned list is only as long as the smallest input list.
fun zipstd/core/zip: forall<a,b> (xs : list<a>, ys : list<b>) -> list<(a, b)>( xsxs: list<_13380> : liststd/core/list: V -> V<aa: V>, ysys: list<_13381> : liststd/core/list: V -> V<bb: V> ) : liststd/core/list: V -> V<(std/core/(,): (V, V) -> Vaa: V,bb: V)std/core/(,): (V, V) -> V>
{
  zipwith-indexedstd/core/zipwith-indexed: forall<a,b,c,e> (xs : list<a>, ys : list<b>, f : (int, a, b) -> e c) -> e list<c>( xsxs: list<_13380>, ysys: list<_13381>, fun(ii: int,xx: _13380,yy: _13381) { (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)xx: _13380,yy: _13381)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b) } )
}

// Zip two lists together by apply a function `f` to all corresponding elements.
// The returned list is only as long as the smallest input list.
fun zipwithstd/core/zipwith: forall<a,b,c,e> (xs : list<a>, ys : list<b>, f : (a, b) -> e c) -> e list<c>( xsxs: list<_26600> : liststd/core/list: V -> V<aa: V>, ysys: list<_26601> :liststd/core/list: V -> V<bb: V>, ff: (_26600, _26601) -> _26603 _26602 : (aa: V,bb: V) -> ee: E cc: V ) : ee: E liststd/core/list: V -> V<cc: V>
{
  zipwith-indexedstd/core/zipwith-indexed: forall<a,b,c,e> (xs : list<a>, ys : list<b>, f : (int, a, b) -> e c) -> e list<c>(xsxs: list<_26600>,ysys: list<_26601>,fun(ii: int,xx: _26600,yy: _26601) { ff: (_26600, _26601) -> _26603 _26602(xx: _26600,yy: _26601) })
}

// Zip two lists together by apply a function `f` to all corresponding elements
// and their index in the list.
// The returned list is only as long as the smallest input list.
fun zipwith-indexedstd/core/zipwith-indexed: forall<a,b,c,e> (xs : list<a>, ys : list<b>, f : (int, a, b) -> e c) -> e list<c>( xsxs: list<_13353> : liststd/core/list: V -> V<aa: V>, ysys: list<_13354> :liststd/core/list: V -> V<bb: V>, ff: (int, _13353, _13354) -> _13356 _13355 : (intstd/core/int: V,aa: V,bb: V) -> ee: E cc: V ) : ee: E liststd/core/list: V -> V<cc: V>
{
  zipwith-iterstd/core/zipwith-iter: forall<a,b,c,e> ((int, a, b) -> e c, int, list<a>, list<b>) -> e list<c>(ff: (int, _13353, _13354) -> _13356 _13355,0,xsxs: list<_13353>,ysys: list<_13354>)
}

// Unzip a list of pairs into two lists
fun unzipstd/core/unzip: forall<a,b> (xs : list<(a, b)>) -> (list<a>, list<b>)( xsxs: list<(_26106, _26107)> : liststd/core/list: V -> V<(std/core/(,): (V, V) -> Vaa: V,bb: V)std/core/(,): (V, V) -> V> ) : (std/core/(,): (V, V) -> Vliststd/core/list: V -> V<aa: V>,liststd/core/list: V -> V<bb: V>)std/core/(,): (V, V) -> V
{
  fun iteriter: forall<a,b> (list<(a, b)>, list<a>, list<b>) -> (list<a>, list<b>)( ysys: list<(_26119, _26120)>, acc1acc1: list<_26119>, acc2acc2: list<_26120> )
  {
    match(ysys: list<(_26119, _26120)>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>((std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)xx: _26119,yy: _26120)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b),xxxx: list<(_26119, _26120)>) -> iteriter: (list<(_26119, _26120)>, list<_26119>, list<_26120>) -> _26114 (list<_26119>, list<_26120>)(xxxx: list<(_26119, _26120)>,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _26119,acc1acc1: list<_26119>),Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _26120,acc2acc2: list<_26120>))
      Nilstd/core/Nil: forall<a> list<a>            -> (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(acc1acc1: list<_26119>),reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(acc2acc2: list<_26120>))std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
    }
  }

  iteriter: forall<a,b> (list<(a, b)>, list<a>, list<b>) -> (list<a>, list<b>)(xsxs: list<(_26106, _26107)>,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>)
}

// Take the first `n` elements of a list (or fewer if the list is shorter than `n`)
fun takestd/core/take: forall<a> (xs : list<a>, n : int) -> list<a>( xsxs: list<_21732> : liststd/core/list: V -> V<aa: V>, nn: int : intstd/core/int: V ) : liststd/core/list: V -> V<aa: V>
{
  if (nstd/core/True: bool <=std/core/(<=).1: (int, int) -> bool 0) returnreturn: list<_21732> Nilstd/core/Nil: forall<a> list<a>
  match(xsxs: list<_21732>) {
    Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21732,xxxx: list<_21732>) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21732,takestd/core/take: forall<a> (xs : list<a>, n : int) -> list<a>(xxxx: list<_21732>,nn: int -std/core/(-): (int, int) -> int 1))
  }
}

// Drop the first `n` elements of a list (or fewer if the list is shorter than `n`)
fun dropstd/core/drop: forall<a> (xs : list<a>, n : int) -> list<a>( xsxs: list<_15867> : liststd/core/list: V -> V<aa: V>, nn: int : intstd/core/int: V ) : liststd/core/list: V -> V<aa: V>
{
  if (nstd/core/True: bool <=std/core/(<=).1: (int, int) -> bool 0) returnreturn: list<_15867> xsxs: list<_15867>
  match(xsxs: list<_15867>) {
    Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(_,xxxx: list<_15867>) -> dropstd/core/drop: forall<a> (xs : list<a>, n : int) -> list<a>(xxxx: list<_15867>,nn: int -std/core/(-): (int, int) -> int 1)
  }
}



// Apply a function `f`  to each element of the input list in sequence.
fun mapstd/core/map.5: forall<a,b,e> (xs : list<a>, f : (a) -> e b) -> e list<b>(xsxs: list<_11260> : liststd/core/list: V -> V<aa: V>, ff: (_11260) -> _11262 _11261 : aa: V -> ee: E bb: V) : ee: E liststd/core/list: V -> V<bb: V>
{
  xsxs: list<_11260>.map-indexed-peekstd/core/map-indexed-peek: forall<a,b,e> (xs : list<a>, f : (idx : int, value : a, rest : list<a>) -> e b) -> e list<b>( fun(ii: int,xx: _11260,xxxx: list<_11260>) { ff: (_11260) -> _11262 _11261(xx: _11260) } )
}

// Apply a function `f`  to each element of the input list in sequence where takes
// both the index of the current element and the element itself as arguments.
fun map-indexedstd/core/map-indexed: forall<a,b,e> (xs : list<a>, f : (idx : int, value : a) -> e b) -> e list<b>(xsxs: list<_22213> : liststd/core/list: V -> V<aa: V>, ff: (idx : int, value : _22213) -> _22215 _22214 : (idx : intstd/core/int: V, value : aa: V) -> ee: E bb: V) : ee: E liststd/core/list: V -> V<bb: V>
{
  xsxs: list<_22213>.map-indexed-peekstd/core/map-indexed-peek: forall<a,b,e> (xs : list<a>, f : (idx : int, value : a, rest : list<a>) -> e b) -> e list<b>( fun(ii: int,xx: _22213,xxxx: list<_22213>) { ff: (idx : int, value : _22213) -> _22215 _22214(ii: int,xx: _22213) })
}

// Apply a function `f`  to each element of the input list in sequence where `f` takes
// both the current element and the tail list as arguments.
fun map-peekstd/core/map-peek: forall<a,b,e> (xs : list<a>, f : (value : a, rest : list<a>) -> e b) -> e list<b>(xsxs: list<_22237> : liststd/core/list: V -> V<aa: V>, ff: (value : _22237, rest : list<_22237>) -> _22239 _22238 : (value : aa: V, rest : liststd/core/list: V -> V<aa: V>) -> ee: E bb: V) : ee: E liststd/core/list: V -> V<bb: V>
{
  xsxs: list<_22237>.map-indexed-peekstd/core/map-indexed-peek: forall<a,b,e> (xs : list<a>, f : (idx : int, value : a, rest : list<a>) -> e b) -> e list<b>( fun(ii: int,xx: _22237,xxxx: list<_22237>) { ff: (value : _22237, rest : list<_22237>) -> _22239 _22238(xx: _22237,xxxx: list<_22237>) })
}


// recurse using an accumulator using constant heap space
private fun map-accstd/core/map-acc: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, acc : list<b>, ys : list<a>) -> e list<b>(gg: (int, _10071, list<_10071>) -> _10073 _10072 : (intstd/core/int: V,aa: V,liststd/core/list: V -> V<aa: V>) -> ee: E bb: V , nn: int : intstd/core/int: V, accacc: list<_10072> : liststd/core/list: V -> V<bb: V>, ysys: list<_10071> : liststd/core/list: V -> V<aa: V>) : ee: E liststd/core/list: V -> V<bb: V> {
  match(ysys: list<_10071>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _10071,xxxx: list<_10071>) -> map-accstd/core/map-acc: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, acc : list<b>, ys : list<a>) -> e list<b>(gg: (int, _10071, list<_10071>) -> _10073 _10072,nn: int+std/core/(+): (int, int) -> int1,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(gg: (int, _10071, list<_10071>) -> _10073 _10072(nn: int,xx: _10071,xxxx: list<_10071>),accacc: list<_10072>),xxxx: list<_10071>)
    Nilstd/core/Nil: forall<a> list<a> -> reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(accacc: list<_10072>)
  }
}

// Apply a function `f`  to each element of the input list in sequence where takes
// both the index of the current element, the element itself, and the tail list as arguments.
fun map-indexed-peekstd/core/map-indexed-peek: forall<a,b,e> (xs : list<a>, f : (idx : int, value : a, rest : list<a>) -> e b) -> e list<b>(xsxs: list<_10138> : liststd/core/list: V -> V<aa: V>, ff: (idx : int, value : _10138, rest : list<_10138>) -> _10140 _10139 : (idx : intstd/core/int: V, value : aa: V, rest : liststd/core/list: V -> V<aa: V> ) -> ee: E bb: V) : ee: E liststd/core/list: V -> V<bb: V>
{
  // recurse for the first `maxListStack` elements over the stack (to avoid extra heap allocation)
  fun map-itermap-iter: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, ys : list<a>) -> e list<b>(gg: (int, _10142, list<_10142>) -> _10144 _10143 : (intstd/core/int: V,aa: V,liststd/core/list: V -> V<aa: V>) -> ee: E bb: V, nn: int : intstd/core/int: V, ysys: list<_10142> : liststd/core/list: V -> V<aa: V>) : ee: E liststd/core/list: V -> V<bb: V> {
    if (nstd/core/True: bool >std/core/(>).1: (int, int) -> bool maxListStackstd/core/maxListStack: int) {
      map-accstd/core/map-acc: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, acc : list<b>, ys : list<a>) -> e list<b>(gg: (int, _10142, list<_10142>) -> _10144 _10143,nn: int,Nilstd/core/Nil: forall<a> list<a>,ysys: list<_10142>)
    }
    else {
      match(ysys: list<_10142>) {
        Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _10142,xxxx: list<_10142>) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(gg: (int, _10142, list<_10142>) -> _10144 _10143(nn: int,xx: _10142,xxxx: list<_10142>),map-itermap-iter: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, ys : list<a>) -> e list<b>(gg: (int, _10142, list<_10142>) -> _10144 _10143,nn: int+std/core/(+): (int, int) -> int1,xxxx: list<_10142>))
        Nilstd/core/Nil: forall<a> list<a>        -> Nilstd/core/Nil: forall<a> list<a>
      }
    }
  }

  returnreturn: list<_10139> map-itermap-iter: forall<a,b,e> (g : (int, a, list<a>) -> e b, n : int, ys : list<a>) -> e list<b>(ff: (idx : int, value : _10138, rest : list<_10138>) -> _10140 _10139,0,xsxs: list<_10138>)
}

// Reverse a list.
fun reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(xsxs: list<_7984> : liststd/core/list: V -> V<aa: V>) : liststd/core/list: V -> V<aa: V>
{
  reverse-appendstd/core/reverse-append: forall<a> (xs : list<a>, tl : list<a>) -> list<a>( xsxs: list<_7984>, Nilstd/core/Nil: forall<a> list<a> )
}

// Efficiently reverse a list `xs` and append it to `tl`:\
// `reverse-append(xs,tl) == reserve(xs) + tl
fun reverse-appendstd/core/reverse-append: forall<a> (xs : list<a>, tl : list<a>) -> list<a>( xsxs: list<_5482> : liststd/core/list: V -> V<aa: V>, tltl: list<_5482> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V>
{
  fun reverse-accreverse-acc: forall<a> (acc : list<a>, ys : list<a>) -> list<a>(accacc: list<_5485> : liststd/core/list: V -> V<aa: V>, ysys: list<_5485> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V> {
    match(ysys: list<_5485>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _5485,xxxx: list<_5485>) -> reverse-accreverse-acc: forall<a> (acc : list<a>, ys : list<a>) -> list<a>(Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _5485,accacc: list<_5485>),xxxx: list<_5485>)
      _          -> accacc: list<_5485>
    }
  }
  reverse-accreverse-acc: forall<a> (acc : list<a>, ys : list<a>) -> list<a>(tltl: list<_5482>,xsxs: list<_5482>)
}

// Append two lists.
fun (+)std/core/(+).4: forall<a> (xs : list<a>, ys : list<a>) -> list<a>(xsxs: list<_8021> : liststd/core/list: V -> V<aa: V>, ysys: list<_8021> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V>
{
  // append using _constant_ stack space (by reversing the argument list)
  fun rev-appendrev-append: forall<a> (list<a>, list<a>) -> list<a>(xxxx: list<_8030>,yyyy: list<_8030>) {
    match(xxxx: list<_8030>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(zz: _8030,zzzz: list<_8030>) -> rev-appendrev-append: (list<_8030>, list<_8030>) -> _8027 list<_8030>(zzzz: list<_8030>,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(zz: _8030,yyyy: list<_8030>))
      _          -> yyyy: list<_8030>
    }
  }
  // append for the first `maxListStack` elements over the stack
  fun appendappend: forall<a> (int, list<a>, list<a>) -> list<a>(nn: int,xxxx: list<_8087>,yyyy: list<_8087>) {
    if (nstd/core/True: bool >std/core/(>).1: (int, int) -> bool maxListStackstd/core/maxListStack: int) {
      rev-appendrev-append: forall<a> (list<a>, list<a>) -> list<a>(reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>(xxxx: list<_8087>),yyyy: list<_8087>)
    }
    else {
      match(xxxx: list<_8087>) {
        Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(zz: _8087,zzzz: list<_8087>) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(zz: _8087,appendappend: (int, list<_8087>, list<_8087>) -> _8052 list<_8087>(nn: int+std/core/(+): (int, int) -> int1,zzzz: list<_8087>,yyyy: list<_8087>))
        Nilstd/core/Nil: forall<a> list<a> -> yyyy: list<_8087>
      }
    }
  }

  match(ysys: list<_8021>) {
    Nilstd/core/Nil: forall<a> list<a> -> xsxs: list<_8021>
    _   -> match(xsxs: list<_8021>) {
             Nilstd/core/Nil: forall<a> list<a> -> ysys: list<_8021>
             _   -> appendappend: forall<a> (int, list<a>, list<a>) -> list<a>(0,xsxs: list<_8021>,ysys: list<_8021>)
           }
  }
}

// Fold a list from the right, i.e. `foldr([1,2],0,(+)) == 1+(2+0)`
// Note, `foldr` is less efficient than `foldl` as it reverses the list first.
fun foldrstd/core/foldr: forall<a,b,e> (xs : list<a>, z : b, f : (a, b) -> e b) -> e b(xsxs: list<_16700>,zz: _16696,ff: (_16700, _16696) -> _16698 _16696)
{
  xsxs: list<_16700>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>.foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b(zz: _16696,fun(xx: _16696,yy: _16700){ff: (_16700, _16696) -> _16698 _16696(yy: _16700,xx: _16696)})
}

// Fold a list from the left, i.e. `foldl([1,2],0,(+)) == (0+1)+2`
// Since `foldl` is tail recursive, it is preferred over `foldr` when using an associative function `f`
fun foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b(xsxs: list<_12992>,zz: _12987,ff: (_12987, _12992) -> _12989 _12987)
{
  match(xsxs: list<_12992>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _12992,xxxx: list<_12992>) -> foldlstd/core/foldl: (list<_12992>, _12987, (_12987, _12992) -> _12989 _12987) -> _12989 _12987(xxxx: list<_12992>,ff: (_12987, _12992) -> _12989 _12987(zz: _12987,xx: _12992),ff: (_12987, _12992) -> _12989 _12987)
    Nilstd/core/Nil: forall<a> list<a>        -> zz: _12987
  }
}

fun foldl1std/core/foldl1: forall<a,e> (xs : list<a>, f : (a, a) -> <exn|e> a) -> <exn|e> a(xsxs: list<_16669> : liststd/core/list: V -> V<aa: V>, ff: (_16669, _16669) -> <exn|_16670> _16669 : (aa: V,aa: V) -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V) : <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V
{
  match(xsxs: list<_16669>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16669,xxxx: list<_16669>) -> xxxx: list<_16669>.foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b(xx: _16669,ff: (_16669, _16669) -> <exn|_16670> _16669)
  }
}

fun foldr1std/core/foldr1: forall<a,e> (xs : list<a>, f : (a, a) -> <exn|e> a) -> <exn|e> a(xsxs: list<_16719> : liststd/core/list: V -> V<aa: V>, ff: (_16719, _16719) -> <exn|_16720> _16719 : (aa: V,aa: V) -> <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V) : <exnstd/core/exn: X|std/core/(<|>): (X, E) -> Eee: E> aa: V
{
  match(xsxs: list<_16719>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16719,Nilstd/core/Nil: forall<a> list<a>) -> xx: _16719
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16719,xxxx: list<_16719>)  -> ff: (_16719, _16719) -> <exn|_16720> _16719(xx: _16719,xxxx: list<_16719>.foldr1std/core/foldr1: forall<a,e> (xs : list<a>, f : (a, a) -> <exn|e> a) -> <exn|e> a(ff: (_16719, _16719) -> <exn|_16720> _16719))
  }
}

// Create a list of `n`  repeated elementes `x`
fun replicatestd/core/replicate: forall<a> (x : a, n : int) -> list<a>( xx: _2497 : aa: V, nn: int : intstd/core/int: V ) : liststd/core/list: V -> V<aa: V>
{
  fun enumerateenumerate: (i : int, acc : list<_2497>) -> list<_2497>( ii: int : intstd/core/int: V, accacc: list<_2497> : liststd/core/list: V -> V<_a_a: V> ) {
    if (istd/core/True: bool <=std/core/(<=).1: (int, int) -> bool 0) then accacc: list<_2497> else enumerateenumerate: (i : int, acc : list<_2497>) -> _2495 list<_2497>(unsafe-decreasingstd/core/unsafe-decreasing: forall<a> (x : a) -> a(ii: int.decstd/core/dec: (i : int) -> int),Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _2497,accacc: list<_2497>))
  }

  enumerateenumerate: (i : int, acc : list<_2497>) -> list<_2497>(nn: int,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>)
}

// split a list at position `n`
fun splitstd/core/split: forall<a> (xs : list<a>, n : int) -> (list<a>, list<a>)( xsxs: list<_21811> : liststd/core/list: V -> V<aa: V>, nn: int : intstd/core/int: V ) : (std/core/(,): (V, V) -> Vliststd/core/list: V -> V<aa: V>, liststd/core/list: V -> V<aa: V>)std/core/(,): (V, V) -> V
{
  (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)xsxs: list<_21811>.takestd/core/take: forall<a> (xs : list<a>, n : int) -> list<a>(nn: int), xsxs: list<_21811>.dropstd/core/drop: forall<a> (xs : list<a>, n : int) -> list<a>(nn: int))std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
}


fun spanstd/core/span: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e (list<a>, list<a>)( xsxs: list<_15941> : liststd/core/list: V -> V<aa: V>, predicatepredicate: (_15941) -> _15942 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E (std/core/(,): (V, V) -> Vliststd/core/list: V -> V<aa: V>,liststd/core/list: V -> V<aa: V>)std/core/(,): (V, V) -> V
{
  fun span-accspan-acc: (list<_15941>, list<_15941>) -> _15942 (list<_15941>, list<_15941>)( ysys: list<_15941>, accacc: list<_15941>)
  {
    match(ysys: list<_15941>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _15941,yyyy: list<_15941>) -> if (ystd/core/True: bool.predicatepredicate: (_15941) -> _15942 bool) then yyyy: list<_15941>.span-accspan-acc: (list<_15941>, list<_15941>) -> _15942 (list<_15941>, list<_15941>)(Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _15941,accacc: list<_15941>)) else (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)accacc: list<_15941>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>,ysys: list<_15941>)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
      _ -> (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)accacc: list<_15941>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>, ysys: list<_15941>)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
    }
  }

  xsxs: list<_15941>.span-accspan-acc: (list<_15941>, list<_15941>) -> _15942 (list<_15941>, list<_15941>)( [std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a> )
}

// Keep only those initial elements that satisfy `predicate`
fun take-whilestd/core/take-while: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e list<a>( xsxs: list<_25545> : liststd/core/list: V -> V<aa: V>, predicatepredicate: (_25545) -> _25546 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E liststd/core/list: V -> V<aa: V>
{
  xsxs: list<_25545>.spanstd/core/span: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e (list<a>, list<a>)(predicatepredicate: (_25545) -> _25546 bool).fststd/core/fst: forall<a,b> ((a, b)) -> a
}

// Drop all initial elements that satisfy `predicate`
fun drop-whilestd/core/drop-while: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e list<a>( xsxs: list<_16001> : liststd/core/list: V -> V<aa: V>, predicatepredicate: (_16001) -> _16002 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E liststd/core/list: V -> V<aa: V>
{
  xsxs: list<_16001>.spanstd/core/span: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e (list<a>, list<a>)(predicatepredicate: (_16001) -> _16002 bool).sndstd/core/snd: forall<a,b> ((a, b)) -> b
}

// Retain only those elements of a list that satisfy the given predicate `pred`.
// For example: `filter([1,2,3],odd?) == [1,3]`
fun filterstd/core/filter: forall<a,e> (xs : list<a>, pred : (a) -> e bool) -> e list<a>( xsxs: list<_16194> : liststd/core/list: V -> V<aa: V>, predpred: (_16194) -> _16195 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E liststd/core/list: V -> V<aa: V>
{
  match(xsxs: list<_16194>) {
    Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16194,xxxx: list<_16194>) -> if (predstd/core/True: bool(xx: _16194)) then Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16194,xxxx: list<_16194>.filterstd/core/filter: forall<a,e> (xs : list<a>, pred : (a) -> e bool) -> e list<a>(predpred: (_16194) -> _16195 bool)) else xxxx: list<_16194>.filterstd/core/filter: forall<a,e> (xs : list<a>, pred : (a) -> e bool) -> e list<a>(predpred: (_16194) -> _16195 bool)
  }
}


// Remove those elements of a list that satisfy the given predicate `pred`.
// For example: `remove([1,2,3],odd?) == [2]`
fun removestd/core/remove: forall<a> (xs : list<a>, pred : (a) -> bool) -> list<a>( xsxs: list<_24207> : liststd/core/list: V -> V<aa: V>, predpred: (_24207) -> bool : aa: V -> boolstd/core/bool: V ) : liststd/core/list: V -> V<aa: V> {
  xsxs: list<_24207>.filterstd/core/filter: forall<a,e> (xs : list<a>, pred : (a) -> e bool) -> e list<a>( fun(xx: _24207) { !std/core/(!): (bool) -> boolpredpred: (_24207) -> bool(xx: _24207) } )
}

// Partition a list in two lists where the first list contains
// those elements that satisfy the given predicate `pred`.
// For example: `partition([1,2,3],odd?) == ([1,3],[2])`
fun partitionstd/core/partition: forall<a> (xs : list<a>, pred : (a) -> bool) -> (list<a>, list<a>)( xsxs: list<_24170> : liststd/core/list: V -> V<aa: V>, predpred: (_24170) -> bool : aa: V -> boolstd/core/bool: V ) : (std/core/(,): (V, V) -> Vliststd/core/list: V -> V<aa: V>,liststd/core/list: V -> V<aa: V>)std/core/(,): (V, V) -> V
{
  partition-accstd/core/partition-acc: forall<a> (xs : list<a>, pred : (a) -> bool, acc1 : list<a>, acc2 : list<a>) -> (list<a>, list<a>)( xsxs: list<_24170>, predpred: (_24170) -> bool, Nilstd/core/Nil: forall<a> list<a>, Nilstd/core/Nil: forall<a> list<a>)
}

private fun partition-accstd/core/partition-acc: forall<a> (xs : list<a>, pred : (a) -> bool, acc1 : list<a>, acc2 : list<a>) -> (list<a>, list<a>)( xsxs: list<_24113> : liststd/core/list: V -> V<aa: V>, predpred: (_24113) -> bool : aa: V -> boolstd/core/bool: V, acc1acc1: list<_24113> : liststd/core/list: V -> V<aa: V>, acc2acc2: list<_24113> : liststd/core/list: V -> V<aa: V> ) : (std/core/(,): (V, V) -> Vliststd/core/list: V -> V<aa: V>, liststd/core/list: V -> V<aa: V>)std/core/(,): (V, V) -> V
{
  match(xsxs: list<_24113>) {
    Nilstd/core/Nil: forall<a> list<a> -> (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)acc1acc1: list<_24113>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>, acc2acc2: list<_24113>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _24113,xxxx: list<_24113>) -> if (predstd/core/True: bool(xx: _24113))
                    then partition-accstd/core/partition-acc: forall<a> (xs : list<a>, pred : (a) -> bool, acc1 : list<a>, acc2 : list<a>) -> (list<a>, list<a>)(xxxx: list<_24113>,predpred: (_24113) -> bool,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _24113,acc1acc1: list<_24113>),acc2acc2: list<_24113>)
                    else partition-accstd/core/partition-acc: forall<a> (xs : list<a>, pred : (a) -> bool, acc1 : list<a>, acc2 : list<a>) -> (list<a>, list<a>)(xxxx: list<_24113>,predpred: (_24113) -> bool,acc1acc1: list<_24113>,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _24113,acc2acc2: list<_24113>))
  }
}


// Retain only those elements of a list that satisfy the given predicate `pred`.
// For example: `filterMap([1,2,3],fun(i) { if (i.odd?) then Nothing else Just(i*i) }) == [4]`
fun filter-mapstd/core/filter-map: forall<a,b,e> (xs : list<a>, pred : (a) -> e maybe<b>) -> e list<b>( xsxs: list<_16232> : liststd/core/list: V -> V<aa: V>, predpred: (_16232) -> _16234 maybe<_16233> : aa: V -> ee: E maybestd/core/maybe: V -> V<bb: V> ) : ee: E liststd/core/list: V -> V<bb: V>
{
  match(xsxs: list<_16232>) {
    Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _16232,xxxx: list<_16232>) -> match(predpred: (_16232) -> _16234 maybe<_16233>(xx: _16232)) {
      Nothingstd/core/Nothing: forall<a> maybe<a> -> xxxx: list<_16232>.filter-mapstd/core/filter-map: forall<a,b,e> (xs : list<a>, pred : (a) -> e maybe<b>) -> e list<b>(predpred: (_16232) -> _16234 maybe<_16233>)
      Juststd/core/Just: forall<a> (value : a) -> maybe<a>(yy: _16233) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _16233,xxxx: list<_16232>.filter-mapstd/core/filter-map: forall<a,b,e> (xs : list<a>, pred : (a) -> e maybe<b>) -> e list<b>(predpred: (_16232) -> _16234 maybe<_16233>))
    }
  }
}

// Find the first element satisfying some predicate
fun findstd/core/find: forall<a> (xs : list<a>, pred : (a) -> bool) -> maybe<a>( xsxs: list<_16293> : liststd/core/list: V -> V<aa: V>, predpred: (_16293) -> bool : aa: V -> boolstd/core/bool: V ) : maybestd/core/maybe: V -> V<aa: V>
{
  xsxs: list<_16293>.foreach-whilestd/core/foreach-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e maybe<b> fun(xx: _16293) {
    if (predstd/core/True: bool(xx: _16293)) then Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _16293) else Nothingstd/core/Nothing: forall<a> maybe<a>
  }
}

// Find the first element satisfying some predicate and return it.
fun find-maybestd/core/find-maybe: forall<a,b> (xs : list<a>, pred : (a) -> maybe<b>) -> maybe<b>( xsxs: list<_16480> : liststd/core/list: V -> V<aa: V>, predpred: (_16480) -> maybe<_16481> : aa: V -> maybestd/core/maybe: V -> V<bb: V> ) : maybestd/core/maybe: V -> V<bb: V>
{
  xsxs: list<_16480>.foreach-whilestd/core/foreach-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e maybe<b>(predpred: (_16480) -> maybe<_16481>)
}

// Lookup the first element satisfying some predicate
fun lookupstd/core/lookup: forall<a,b> (xs : list<(a, b)>, pred : (a) -> bool) -> maybe<b>( xsxs: list<(_21994, _21995)> : liststd/core/list: V -> V<(std/core/(,): (V, V) -> Vaa: V,bb: V)std/core/(,): (V, V) -> V>, predpred: (_21994) -> bool : aa: V -> boolstd/core/bool: V ) : maybestd/core/maybe: V -> V<bb: V>
{
  xsxs: list<(_21994, _21995)>.foreach-whilestd/core/foreach-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e maybe<b> fun(kvkv: (_21994, _21995)) {
    if (predstd/core/True: bool(kvkv: (_21994, _21995).fststd/core/fst: forall<a,b> ((a, b)) -> a)) then Juststd/core/Just: forall<a> (value : a) -> maybe<a>(kvkv: (_21994, _21995).sndstd/core/snd: forall<a,b> ((a, b)) -> b) else Nothingstd/core/Nothing: forall<a> maybe<a>
  }
}

// Convert a list to a `:maybe` type, using `Nothing` for an empty list, and otherwise `Just` on the head element.
// Note: this is just `head`.
fun maybestd/core/maybe.5: forall<a> (xs : list<a>) -> maybe<a>( xsxs: list<_22573> : liststd/core/list: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<aa: V>
{
  match(xsxs: list<_22573>) {
    Nilstd/core/Nil: forall<a> list<a> -> Nothingstd/core/Nothing: forall<a> maybe<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _22573,_) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _22573)
  }
}

// Convert a `:maybe` type to a list type.
fun liststd/core/list.3: forall<a> (m : maybe<a>) -> list<a>( mm: maybe<_12117> : maybestd/core/maybe: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V>
{
  match(mm: maybe<_12117>) {
    Nothingstd/core/Nothing: forall<a> maybe<a> -> Nilstd/core/Nil: forall<a> list<a>
    Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _12117) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _12117,Nilstd/core/Nil: forall<a> list<a>)
  }
}

private fun index-of-accstd/core/index-of-acc: forall<a> (xs : list<a>, pred : (a) -> bool, idx : int) -> int( xsxs: list<_21332> : liststd/core/list: V -> V<aa: V>, predpred: (_21332) -> bool : aa: V -> boolstd/core/bool: V, idxidx: int : intstd/core/int: V ) : intstd/core/int: V
{
  match(xsxs: list<_21332>) {
    Nilstd/core/Nil: forall<a> list<a> -> 0 -std/core/(-): (int, int) -> int 1
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21332,xxxx: list<_21332>) -> if (predstd/core/True: bool(xx: _21332)) then idxidx: int else index-of-accstd/core/index-of-acc: forall<a> (xs : list<a>, pred : (a) -> bool, idx : int) -> int(xxxx: list<_21332>,predpred: (_21332) -> bool,idxidx: int+std/core/(+): (int, int) -> int1)
  }
}

// Returns the index of the first element where `pred` holds, or `-1` if no such element exists.
fun index-ofstd/core/index-of: forall<a> (xs : list<a>, pred : (a) -> bool) -> int( xsxs: list<_21407> : liststd/core/list: V -> V<aa: V>, predpred: (_21407) -> bool : aa: V -> boolstd/core/bool: V ) : intstd/core/int: V
{
  index-of-accstd/core/index-of-acc: forall<a> (xs : list<a>, pred : (a) -> bool, idx : int) -> int( xsxs: list<_21407>, predpred: (_21407) -> bool, 0 )
}

// Invoke `action` for each element of a list
fun foreachstd/core/foreach: forall<a,e> (xs : list<a>, action : (a) -> e ()) -> e ()( xsxs: list<_15195> : liststd/core/list: V -> V<aa: V>, actionaction: (_15195) -> _15196 () : (aa: V) -> ee: E (std/core/(): V)std/core/(): V ) : ee: E (std/core/(): V)std/core/(): V
{
  match(xsxs: list<_15195>) {
    Nilstd/core/Nil: forall<a> list<a>        -> returnreturn: () (std/core/(): ())std/core/(): ()
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _15195,xxxx: list<_15195>) -> { actionaction: (_15195) -> _15196 ()(xx: _15195); xxxx: list<_15195>.foreachstd/core/foreach: forall<a,e> (xs : list<a>, action : (a) -> e ()) -> e ()(actionaction: (_15195) -> _15196 ()) }
  }
}

// Invoke `action` for each element of a list while `action` return `Nothing`
fun foreach-whilestd/core/foreach-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e maybe<b>( xsxs: list<_14789> : liststd/core/list: V -> V<aa: V>, actionaction: (_14789) -> _14791 maybe<_14790> : (aa: V) -> ee: E maybestd/core/maybe: V -> V<bb: V> ) : ee: E maybestd/core/maybe: V -> V<bb: V>
{
  match(xsxs: list<_14789>) {
    Nilstd/core/Nil: forall<a> list<a>        -> Nothingstd/core/Nothing: forall<a> maybe<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _14789,xxxx: list<_14789>) -> {
      match(actionaction: (_14789) -> _14791 maybe<_14790>(xx: _14789)) {
        Nothingstd/core/Nothing: forall<a> maybe<a> -> xxxx: list<_14789>.foreach-whilestd/core/foreach-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e maybe<b>(actionaction: (_14789) -> _14791 maybe<_14790>)
        justjust: maybe<_14790>    -> justjust: maybe<_14790>
      }
    }
  }
}

// Invoke `action` on each element of a list while `action` returns `Just`
fun map-whilestd/core/map-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e list<b>( xsxs: list<_22261> : liststd/core/list: V -> V<aa: V>, actionaction: (_22261) -> _22263 maybe<_22262> : (aa: V) -> ee: E maybestd/core/maybe: V -> V<bb: V> ) : ee: E liststd/core/list: V -> V<bb: V>
{
  match(xsxs: list<_22261>) {
    Nilstd/core/Nil: forall<a> list<a>        -> Nilstd/core/Nil: forall<a> list<a>
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _22261,xxxx: list<_22261>) -> {
      match(actionaction: (_22261) -> _22263 maybe<_22262>(xx: _22261)) {
        Juststd/core/Just: forall<a> (value : a) -> maybe<a>(yy: _22262) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _22262,xxxx: list<_22261>.map-whilestd/core/map-while: forall<a,b,e> (xs : list<a>, action : (a) -> e maybe<b>) -> e list<b>(actionaction: (_22261) -> _22263 maybe<_22262>))
        Nothingstd/core/Nothing: forall<a> maybe<a> -> Nilstd/core/Nil: forall<a> list<a>
      }
    }
  }
}

// Invoke `action` for each element of a list, passing also the position of the element.
fun foreach-indexedstd/core/foreach-indexed: forall<a,e> (xs : list<a>, action : (int, a) -> e ()) -> e ()( xsxs: list<_16922> : liststd/core/list: V -> V<aa: V>, actionaction: (int, _16922) -> _16923 () : (intstd/core/int: V,aa: V) -> ee: E (std/core/(): V)std/core/(): V ) : ee: E (std/core/(): V)std/core/(): V
{
  varstd/core/local-var: forall<h,e,a,b> (value : a, action : (v : local-var<h,a>) -> <local<h>|e> b) -> <local<h>|e> b ii: local-var<_2087,int> := 0
  xsxs: list<_16922>.foreachstd/core/foreach: forall<a,e> (xs : list<a>, action : (a) -> e ()) -> e () fun(xx: _16922) {
    val jj: int = istd/core/local-get: forall<h,a,e> (v : local-var<h,a>) -> <local<h>|e> a with hdiv<h,a,e>; // don't dereference `i` inside the inject
    inject_1: H<localstd/core/local: H -> X>{actionaction: (int, _16922) -> _16923 ()(jj: int,xx: _16922)}
    ii: local-var<_2087,int> :=std/core/local-set: forall<h,a,b> (v : local-var<h,a>, assigned : a) -> (local<h>) () istd/core/local-get: forall<h,a,e> (v : local-var<h,a>) -> <local<h>|e> a with hdiv<h,a,e>+std/core/(+): (int, int) -> int1
  }
}

// Insert a separator `sep`  between all elements of a list `xs` .
fun interspersestd/core/intersperse: forall<a> (xs : list<a>, sep : a) -> list<a>( xsxs: list<_6258> : liststd/core/list: V -> V<aa: V>, sepsep: _6258 : aa: V ) : liststd/core/list: V -> V<aa: V>
{
  //TODO: make tail recursive
  fun beforebefore: forall<a> (list<a>, a) -> list<a>(ysys: list<_6263>,ss: _6263) {
    match(ysys: list<_6263>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _6263,yyyy: list<_6263>) -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(ss: _6263,Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: _6263,beforebefore: (list<_6263>, _6263) -> _6264 list<_6263>(yyyy: list<_6263>,ss: _6263)))
      Nilstd/core/Nil: forall<a> list<a>        -> Nilstd/core/Nil: forall<a> list<a>
    }
  }

  match(xsxs: list<_6258>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _6258,xxxx: list<_6258>)  -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _6258, xxxx: list<_6258>.beforebefore: forall<a> (list<a>, a) -> list<a>(sepsep: _6258))
    Nilstd/core/Nil: forall<a> list<a>         -> Nilstd/core/Nil: forall<a> list<a>
  }
}

// Concatenate all strings in a list
private fun joinsepstd/core/joinsep: (xs : list<string>, sep : string) -> string( xsxs: list<string> : liststd/core/list: V -> V<stringstd/core/string: V>, sepsep: string : stringstd/core/string: V ) : stringstd/core/string: V
{
  fun join-accjoin-acc: (ys : list<string>, acc : string) -> string( ysys: list<string> : liststd/core/list: V -> V<stringstd/core/string: V>, accacc: string : stringstd/core/string: V ) {
    match(ysys: list<string>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(yy: string,yyyy: list<string>) -> join-accjoin-acc: (ys : list<string>, acc : string) -> _2111 string(yyyy: list<string>, accacc: string +std/core/(+).3: (string, string) -> string sepsep: string +std/core/(+).3: (string, string) -> string yy: string)  // todo: use string builder
      Nilstd/core/Nil: forall<a> list<a> -> accacc: string
    }
  }
  match(xsxs: list<string>) {
    Nilstd/core/Nil: forall<a> list<a> -> ""
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: string,xxxx: list<string>) -> join-accjoin-acc: (ys : list<string>, acc : string) -> string(xxxx: list<string>,xx: string)
  }
}

// Concatenate all strings in a list
fun joinstd/core/join.2: (xs : list<string>) -> string( xsxs: list<string> : liststd/core/list: V -> V<stringstd/core/string: V> ) : stringstd/core/string: V {
  returnreturn: string xsxs: list<string>.joinsepstd/core/joinsep: (xs : list<string>, sep : string) -> string("")
}

// Concatenate all strings in a list using a specific separator
fun joinstd/core/join.3: (xs : list<string>, sep : string) -> string( xsxs: list<string> : liststd/core/list: V -> V<stringstd/core/string: V>, sepsep: string : stringstd/core/string: V ) : stringstd/core/string: V {
  returnreturn: string xsxs: list<string>.joinsepstd/core/joinsep: (xs : list<string>, sep : string) -> string(sepsep: string)
}


// Append `end` to each string in the list `xs` and join them all together.\
// `join-end([],end) === ""`\
// `join-end(["a","b"],"/") === "a/b/"`
public fun join-endstd/core/join-end: (xs : list<string>, end : string) -> string( xsxs: list<string> : liststd/core/list: V -> V<stringstd/core/string: V>, endend: string : stringstd/core/string: V) : stringstd/core/string: V {
  match(xsxs: list<string>) {
    Nilstd/core/Nil: forall<a> list<a> -> ""
    _   -> xsxs: list<string>.joinsepstd/core/joinsep: (xs : list<string>, sep : string) -> string(endend: string) +std/core/(+).3: (string, string) -> string endend: string
  }
}


// Concatenate all lists in a list (e.g. flatten the list). (tail-recursive)
fun concatstd/core/concat: forall<a> (xs : list<list<a>>) -> list<a>( xsxs: list<list<_14411>> : liststd/core/list: V -> V<liststd/core/list: V -> V<aa: V>> ) : liststd/core/list: V -> V<aa: V>
{
  fun concat-revconcat-rev: forall<a> (xss : list<list<a>>, acc : list<a>) -> list<a>( xssxss: list<list<_14414>> : liststd/core/list: V -> V<liststd/core/list: V -> V<aa: V>>, accacc: list<_14414> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V> {
    match(xssxss: list<list<_14414>>) {
      Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(ysys: list<_14414>,yssyss: list<list<_14414>>) -> concat-revconcat-rev: forall<a> (xss : list<list<a>>, acc : list<a>) -> list<a>( yssyss: list<list<_14414>>, ysys: list<_14414> +std/core/(+).4: forall<a> (xs : list<a>, ys : list<a>) -> list<a> accacc: list<_14414> )
      Nilstd/core/Nil: forall<a> list<a>          -> accacc: list<_14414>
    }
  }
  concat-revconcat-rev: forall<a> (xss : list<list<a>>, acc : list<a>) -> list<a>(xsxs: list<list<_14411>>.reversestd/core/reverse: forall<a> (xs : list<a>) -> list<a>,[std/core/Nil: forall<a> list<a>]std/core/Nil: forall<a> list<a>)
}

// Concatenate the result lists from applying a function to all elements.
fun flatmapstd/core/flatmap: forall<a,b,e> (xs : list<a>, f : (a) -> e list<b>) -> e list<b>( xsxs: list<_16547>: liststd/core/list: V -> V<aa: V>, ff: (_16547) -> _16549 list<_16548> : aa: V -> ee: E liststd/core/list: V -> V<bb: V> ) : ee: E liststd/core/list: V -> V<bb: V>
{
  xsxs: list<_16547>.mapstd/core/map.5: forall<a,b,e> (xs : list<a>, f : (a) -> e b) -> e list<b>(ff: (_16547) -> _16549 list<_16548>).concatstd/core/concat: forall<a> (xs : list<list<a>>) -> list<a>()
}

// Concatenate a list of `:maybe` values
fun concat-maybestd/core/concat-maybe: forall<a> (xs : list<maybe<a>>) -> list<a>( xsxs: list<maybe<_14488>> : liststd/core/list: V -> V<maybestd/core/maybe: V -> V<aa: V>> ) : liststd/core/list: V -> V<aa: V>
{
  xsxs: list<maybe<_14488>>.mapstd/core/map.5: forall<a,b,e> (xs : list<a>, f : (a) -> e b) -> e list<b>(liststd/core/list.3: forall<a> (m : maybe<a>) -> list<a>).concatstd/core/concat: forall<a> (xs : list<list<a>>) -> list<a>()
}

// Return the last element of a list (or `Nothing` for the empty list)
fun laststd/core/last: forall<a> (xs : list<a>) -> maybe<a>( xsxs: list<_21523> : liststd/core/list: V -> V<aa: V> ) : maybestd/core/maybe: V -> V<aa: V>
{
  match(xsxs: list<_21523>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21523,Nilstd/core/Nil: forall<a> list<a>) -> Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _21523)
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(_,xxxx: list<_21523>)  -> laststd/core/last: forall<a> (xs : list<a>) -> maybe<a>(xxxx: list<_21523>)
    Nilstd/core/Nil: forall<a> list<a>         -> Nothingstd/core/Nothing: forall<a> maybe<a>
  }
}

// Return the last element of a list (or `default` for the empty list)
fun laststd/core/last.1: forall<a> (xs : list<a>, default : a) -> a( xsxs: list<_21569> : liststd/core/list: V -> V<aa: V>, defaultdefault: _21569 : aa: V ) : astd/core/(<>): E
{
  match(xsxs: list<_21569>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21569,Nilstd/core/Nil: forall<a> list<a>) -> xx: _21569
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(_,xxxx: list<_21569>)  -> laststd/core/last.1: forall<a> (xs : list<a>, default : a) -> a(xxxx: list<_21569>,defaultdefault: _21569)
    Nilstd/core/Nil: forall<a> list<a>         -> defaultdefault: _21569
  }
}

// Return the list without its last element.
// Return an empty list for an empty list.
fun initstd/core/init: forall<a> (xs : list<a>) -> list<a>( xsxs: list<_21422> : liststd/core/list: V -> V<aa: V> ) : liststd/core/list: V -> V<aa: V>
{
  match(xsxs: list<_21422>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21422,xxxx: list<_21422>)  -> match(xxxx: list<_21422>) {
                     Nilstd/core/Nil: forall<a> list<a> -> Nilstd/core/Nil: forall<a> list<a>
                     _   -> Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _21422,initstd/core/init: forall<a> (xs : list<a>) -> list<a>(xxxx: list<_21422>))
                   }
    Nilstd/core/Nil: forall<a> list<a>         -> Nilstd/core/Nil: forall<a> list<a>
  }
}

// Get (zero-based) element `n`  of a list. Return a `:maybe` type.
fun [std/core/[].2: forall<a> (xs : list<a>, n : int) -> maybe<a>]( xsxs: list<_9095> : liststd/core/list: V -> V<aa: V>, nn: int : intstd/core/int: V ) : maybestd/core/maybe: V -> V<aa: V>
{
  match(xsxs: list<_9095>) {
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _9095,xxxx: list<_9095>) -> if (nstd/core/True: bool==std/core/(==).1: (int, int) -> bool0) then Juststd/core/Just: forall<a> (value : a) -> maybe<a>(xx: _9095) else xxxx: list<_9095>[std/core/[].2: forall<a> (xs : list<a>, n : int) -> maybe<a>nn: int -std/core/(-): (int, int) -> int 1]
    Nilstd/core/Nil: forall<a> list<a> -> Nothingstd/core/Nothing: forall<a> maybe<a>
  }
}

// Do all elements satisfy a predicate ?
fun allstd/core/all: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e bool( xsxs: list<_9646> : liststd/core/list: V -> V<aa: V>, predicatepredicate: (_9646) -> _9647 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E boolstd/core/bool: V
{
  match(xsxs: list<_9646>) {
    Nilstd/core/Nil: forall<a> list<a> -> Truestd/core/True: bool
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _9646,xxxx: list<_9646>) -> if (predicatestd/core/True: bool(xx: _9646)) then xxxx: list<_9646>.allstd/core/all: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e bool(predicatepredicate: (_9646) -> _9647 bool) else Falsestd/core/False: bool
  }
}


// Are there any elements in a list that satisfy a predicate ?
fun anystd/core/any: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e bool( xsxs: list<_9675> : liststd/core/list: V -> V<aa: V>, predicatepredicate: (_9675) -> _9676 bool : aa: V -> ee: E boolstd/core/bool: V ) : ee: E boolstd/core/bool: V
{
  match(xsxs: list<_9675>) {
    Nilstd/core/Nil: forall<a> list<a> -> Falsestd/core/False: bool
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: _9675,xxxx: list<_9675>) -> if (predicatestd/core/True: bool(xx: _9675)) then Truestd/core/True: bool else xxxx: list<_9675>.anystd/core/any: forall<a,e> (xs : list<a>, predicate : (a) -> e bool) -> e bool(predicatepredicate: (_9675) -> _9676 bool)
  }
}

// ----------------------------------------------------------------------------
// Characters
// ----------------------------------------------------------------------------

extern inline (==)std/core/(==): (char, char) -> bool : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 == #2)"; js inline "(#1 === #2)" }
extern inline (!=)std/core/(!=): (char, char) -> bool : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 != #2)"; js inline "(#1 !== #2)" }
extern inline (<=)std/core/(<=): (char, char) -> bool : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 <= #2)" }
extern inline (>=)std/core/(>=): (char, char) -> bool : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 >= #2)" }
extern inline (<)std/core/(<): (char, char) -> bool  : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 < #2)" }
extern inline (>)std/core/(>): (char, char) -> bool  : (charstd/core/char: V,charstd/core/char: V) -> boolstd/core/bool: V  { inline "(#1 > #2)" }

fun comparestd/core/compare.1: (x : char, y : char) -> order( xx: char : charstd/core/char: V, yy: char : charstd/core/char: V ) : orderstd/core/order: V
{
  if (xstd/core/True: bool <std/core/(<): (char, char) -> bool yy: char) then Ltstd/core/Lt: order
  elif (xstd/core/True: bool >std/core/(>): (char, char) -> bool yy: char) then Gtstd/core/Gt: order
  else Eqstd/core/Eq: order
}

// Convert a character to its unicode code point
extern inline intstd/core/int: (char) -> int : (charstd/core/char: V) -> intstd/core/int: V { inline "#1"; cs inline "new BigInteger(#1)" }

// Convert a unicode code point to a character
extern inline charstd/core/char: (int) -> char : (intstd/core/int: V) -> charstd/core/char: V { inline "(#1)"; cs inline "Primitive.IntToInt32(#1)" }

// Add two character code points
fun (+)std/core/(+).5: (c : char, d : char) -> total char(cc: char : charstd/core/char: V, dd: char : charstd/core/char: V) : totalstd/core/total: E charstd/core/char: V { (cc: char.intstd/core/int: (char) -> int +std/core/(+): (int, int) -> int dd: char.intstd/core/int: (char) -> int).charstd/core/char: (int) -> char }
// Substract two character codePoints
fun (-)std/core/(-).3: (c : char, d : char) -> total char(cc: char : charstd/core/char: V, dd: char : charstd/core/char: V) : totalstd/core/total: E charstd/core/char: V { (cc: char.intstd/core/int: (char) -> int -std/core/(-): (int, int) -> int dd: char.intstd/core/int: (char) -> int).charstd/core/char: (int) -> char }

// Is the character a lower-case ASCII character ?
fun lower?std/core/lower?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char >=std/core/(>=): (char, char) -> bool 'a' &&std/core/(&&): (bool, bool) -> bool cc: char <=std/core/(<=): (char, char) -> bool 'z' }
// Is the character an upper-case ASCII character ?
fun upper?std/core/upper?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char >=std/core/(>=): (char, char) -> bool 'A' &&std/core/(&&): (bool, bool) -> bool cc: char <=std/core/(<=): (char, char) -> bool 'Z' }
// Is the character an ASCII digit ?
fun digit?std/core/digit?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char >=std/core/(>=): (char, char) -> bool '0' &&std/core/(&&): (bool, bool) -> bool cc: char <=std/core/(<=): (char, char) -> bool '9' }
// Is the character an ASCII hexa-decimal digit ?
fun hex-digit?std/core/hex-digit?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char.digit?std/core/digit?: (c : char) -> bool ||std/core/(||): (bool, bool) -> bool (cc: char >=std/core/(>=): (char, char) -> bool 'a' &&std/core/(&&): (bool, bool) -> bool cc: char <=std/core/(<=): (char, char) -> bool 'f') ||std/core/(||): (bool, bool) -> bool (cc: char >=std/core/(>=): (char, char) -> bool 'A'  &&std/core/(&&): (bool, bool) -> bool cc: char <=std/core/(<=): (char, char) -> bool 'F') }
// Is the character an ASCII letter ?
fun alpha?std/core/alpha?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char.lower?std/core/lower?: (c : char) -> bool ||std/core/(||): (bool, bool) -> bool cc: char.upper?std/core/upper?: (c : char) -> bool }
// Is the character ASCII letter or digit?
fun alpha-num?std/core/alpha-num?: (c : char) -> bool( cc: char : charstd/core/char: V ) : boolstd/core/bool: V { cc: char.alpha?std/core/alpha?: (c : char) -> bool ||std/core/(||): (bool, bool) -> bool cc: char.digit?std/core/digit?: (c : char) -> bool }
// Is the character an ASCII character, e.g. `c <= '\x7F'`  ?
fun ascii?std/core/ascii?: (c : char) -> bool( cc: char : charstd/core/char: V )     : boolstd/core/bool: V { cc: char <=std/core/(<=): (char, char) -> bool '\DEL' }
// Is the character an ASCII control character, e.g. `c < ' '`  ?
fun control?std/core/control?: (c : char) -> bool( cc: char : charstd/core/char: V )   : boolstd/core/bool: V { cc: char <std/core/(<): (char, char) -> bool ' ' }
// Tests if a character is an element of `" \t\n\r"`
fun white?std/core/white?: (c : char) -> bool( cc: char : charstd/core/char: V )     : boolstd/core/bool: V { cc: char ==std/core/(==): (char, char) -> bool ' ' ||std/core/(||): (bool, bool) -> bool cc: char ==std/core/(==): (char, char) -> bool '\t' ||std/core/(||): (bool, bool) -> bool cc: char ==std/core/(==): (char, char) -> bool '\n' ||std/core/(||): (bool, bool) -> bool cc: char ==std/core/(==): (char, char) -> bool '\r' }


// ----------------------------------------------------------------------------
// Booleans
// ----------------------------------------------------------------------------

// For short-circuiting we use extern here
// fun (&&)( x : bool, y : bool) : bool = if (x) then y else false
// fun (||)( x : bool, y : bool) : bool = if (x) then true else y

extern inline (&&)std/core/(&&): (bool, bool) -> bool : (boolstd/core/bool: V,boolstd/core/bool: V) -> boolstd/core/bool: V  { inline "(#1 && #2)" }
extern inline (||)std/core/(||): (bool, bool) -> bool : (boolstd/core/bool: V,boolstd/core/bool: V) -> boolstd/core/bool: V  { inline "(#1 || #2)" }

// for efficiency we use extern here
// fun (!)( b : bool ) : bool = if (x) then false else true
// fun not( b : bool ) : bool = if (x) then false else true

extern inline notstd/core/not: (bool) -> bool  : (boolstd/core/bool: V) -> boolstd/core/bool: V  { inline "!(#1)" }
extern inline (!)std/core/(!): (bool) -> bool  : (boolstd/core/bool: V) -> boolstd/core/bool: V  { inline "!(#1)" }

fun (==)std/core/(==).5: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V { if (xx: bool) then yy: bool else !std/core/(!): (bool) -> boolyy: bool }
fun (!=)std/core/(!=).5: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V { if (xx: bool) then !std/core/(!): (bool) -> boolyy: bool else yy: bool }

fun (<)std/core/(<).5: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V  { (!std/core/(!): (bool) -> boolxx: bool &&std/core/(&&): (bool, bool) -> bool yy: bool) }
fun (<=)std/core/(<=).5: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V { !std/core/(!): (bool) -> bool(xx: bool >std/core/(>).4: (x : bool, y : bool) -> bool yy: bool) }
fun (>)std/core/(>).4: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V  { (xx: bool &&std/core/(&&): (bool, bool) -> bool !std/core/(!): (bool) -> boolyy: bool) }
fun (>=)std/core/(>=).4: (x : bool, y : bool) -> bool( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : boolstd/core/bool: V { !std/core/(!): (bool) -> bool(xx: bool <std/core/(<).5: (x : bool, y : bool) -> bool yy: bool) }

fun comparestd/core/compare.2: (x : bool, y : bool) -> order( xx: bool : boolstd/core/bool: V, yy: bool : boolstd/core/bool: V) : orderstd/core/order: V
{
  if (xstd/core/True: bool <std/core/(<).5: (x : bool, y : bool) -> bool yy: bool) then Ltstd/core/Lt: order
  elif (xstd/core/True: bool >std/core/(>).4: (x : bool, y : bool) -> bool yy: bool) then Gtstd/core/Gt: order
  else Eqstd/core/Eq: order
}

// Transform a boolean to a maybe type, using `Nothing` for `False`
fun maybestd/core/maybe.6: (b : bool) -> maybe<()>( bb: bool : boolstd/core/bool: V ) : maybestd/core/maybe: V -> V<(std/core/(): V)std/core/(): V> {
    if (bb: bool) then Juststd/core/Just: forall<a> (value : a) -> maybe<a>((std/core/(): ())std/core/(): ()) else Nothingstd/core/Nothing: forall<a> maybe<a>
}

// ----------------------------------------------------------------------------
// Integers
// ----------------------------------------------------------------------------

// Compare two integers
extern inline comparestd/core/compare: (int, int) -> order : (intstd/core/int: V,intstd/core/int: V) -> orderstd/core/order: V  {
  cs "Primitive.IntCompare"
  js "$std_core._int_compare"
}


// Are two integers equal?
extern inline (==)std/core/(==): (int, int) -> bool : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 == #2)"
  js "$std_core._int_eq"
}

// Are two integers not equal?
extern inline (!=)std/core/(!=): (int, int) -> bool : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 != #2)"
  js "$std_core._int_ne"
}

// Is the first integer smaller or equal to the second?
extern inline (<=)std/core/(<=): (int, int) -> bool : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 <= #2)"
  js "$std_core._int_le"
}

// Is the first integer greater or equal to the second?
extern inline (>=)std/core/(>=): (int, int) -> bool : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 >= #2)"
  js "$std_core._int_ge"
}

// Is the first integer smaller than the second?
extern inline (<)std/core/(<): (int, int) -> bool  : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 < #2)"
  js "$std_core._int_lt"
}

// Is the first integer greater than the second?
extern inline (>)std/core/(>): (int, int) -> bool  : (intstd/core/int: V,intstd/core/int: V) -> boolstd/core/bool: V  {
  cs inline "(#1 > #2)"
  js "$std_core._int_gt"
}

// Add two integers.
extern inline (+)std/core/(+): (int, int) -> int : (intstd/core/int: V,intstd/core/int: V) -> intstd/core/int: V {
  cs inline "(#1 + #2)"
  js "$std_core._int_add"
}

// Substract two integers.
extern inline (-)std/core/(-): (int, int) -> int : (intstd/core/int: V,intstd/core/int: V) -> intstd/core/int: V {
  cs inline "(#1 - #2)"
  js "$std_core._int_sub"
}

// Multiply two integers.
extern inline (*)std/core/(*): (int, int) -> int : (intstd/core/int: V,intstd/core/int: V) -> intstd/core/int: V {
  cs inline "(#1 * #2)"
  js "$std_core._int_mul"
}

// Euclidean-0 division of two integers. See also `divmod:(x : int, y : int) -> (int,int)`.
extern inline (/)std/core/(/): (x : int, y : int) -> int(x:intstd/core/int: V,y:intstd/core/int: V) : intstd/core/int: V {
  cs "Primitive.IntDiv"
  js "$std_core._int_div"
}
// Euclidean modulus of two integers; always a non-negative number. See also `divmod:(x : int, y : int) -> (int,int)`.
extern inline (%)std/core/(%): (int, int) -> int  : (intstd/core/int: V,intstd/core/int: V) -> intstd/core/int: V {
  cs "Primitive.IntMod"
  js "$std_core._int_mod"
}

// Euclidean-0 division & modulus.
// Euclidean division is defined as: For any `D`  and `d`  where `d!=0` , we have:
//
// 1. `D == d*(D/d) + (D%d)`
// 2. `D%d`  is always positive where `0 <= D%d < abs(d)`
//
// Moreover, Euclidean-0 is a total function, for the case where `d==0`  we have
// that `D%0 == D`  and `D/0 == 0` . So property (1) still holds, but not property (2).
//
// Useful laws that hold for Euclidean-0 division:
//
// * `D/(-d) == -(D/d)`
// * `D%(-d) == D%d`
// * `D/(2^n) == sar(D,n)         `  (with `0 <= n <= 31`  and `2^n`  means `2`  to the power of `n` )
// * `D%(2^n) == D & ((2^n) - 1)  `  (with `0 <= n <= 31`  and `2^n`  means `2`  to the power of `n` )
//
// See also _Division and modulus for computer scientists, Daan Leijen, 2001_ for further information
// available at: <http://research.microsoft.com/pubs/151917/divmodnote.pdf> .
extern inline divmodstd/core/divmod: (x : int, y : int) -> (int, int)(x:intstd/core/int: V,y:intstd/core/int: V) : (std/core/(,): (V, V) -> Vintstd/core/int: V,intstd/core/int: V)std/core/(,): (V, V) -> V {
  cs "Primitive.IntDivMod"
  js "$std_core._int_divmod"
}

fun negatestd/core/negate: (i : int) -> int(ii: int : intstd/core/int: V) : intstd/core/int: V {
  ~std/core/(~): (i : int) -> intii: int
}

// Negate an integer.
extern inline (~)std/core/(~): (i : int) -> int(i:intstd/core/int: V) : intstd/core/int: V {
  cs inline "(-#1)"
  js "$std_core._int_negate"
}

// Convert an integer to a `:double`. May return `nan` if the integer is too large to represent as a `:double`.
extern inline doublestd/core/double: (int) -> double : (intstd/core/int: V) -> doublestd/core/double: V  {
  cs "Primitive.IntToDouble"
  js "$std_core._int_to_double"
}

// Is this an odd integer?
extern inline odd?std/core/odd?: (int) -> bool   : ( intstd/core/int: V ) -> boolstd/core/bool: V  {
  cs inline "!(#1.IsEven)"
  js "$std_core._int_isodd"
}

// Is this equal to zero?
extern inline zero?std/core/zero?: (int) -> bool  : ( intstd/core/int: V ) -> boolstd/core/bool: V  {
  cs inline "(#1.IsZero)"
  js "$std_core._int_iszero"
}


// Return the absolute value of an integer.
extern inline absstd/core/abs: (i : int) -> int(i : intstd/core/int: V) : intstd/core/int: V {
  cs "BigInteger.Abs"
  js "$std_core._int_abs"
}

fun incstd/core/inc: (i : int) -> int( ii: int : intstd/core/int: V ) : intstd/core/int: V {
  ii: int +std/core/(+): (int, int) -> int 1
}

fun decstd/core/dec: (i : int) -> int( ii: int : intstd/core/int: V ) : intstd/core/int: V {
  ii: int -std/core/(-): (int, int) -> int 1
}

// Calculate `10^exp`
fun exp10std/core/exp10: (exp : int) -> int( expexp: int : intstd/core/int: V ) : intstd/core/int: V {
  1.mul-exp10std/core/mul-exp10: (i : int, n : int) -> int(expexp: int)
}

// Raise an integer `i` to the power of `exp`.
extern powstd/core/pow: (i : int, exp : int) -> int( ii: int : intstd/core/int: V, expexp: int : intstd/core/int: V ) : intstd/core/int: V {
	cs "Primitive.IntPow"
	js "_int_pow"
}

// Raise an integer `i` to the power of `exp`.
fun (^)std/core/(^).1: (i : int, exp : int) -> int(ii: int : intstd/core/int: V, expexp: int : intstd/core/int: V ) : intstd/core/int: V {
	powstd/core/pow: (i : int, exp : int) -> int(ii: int,expexp: int);
}

// Calculate `2^exp`.
fun exp2std/core/exp2: (exp : int) -> int( expexp: int : intstd/core/int: V ) : intstd/core/int: V {
	powstd/core/pow: (i : int, exp : int) -> int(2,expexp: int)
}

// Return the number of ending `0` digits of `i`. Return `0` when `i==0`.
extern exp10?std/core/exp10?: (i : int) -> int( ii: int : intstd/core/int: V ) : intstd/core/int: V {
  cs "Primitive.IntCountPow10"
  js "_int_count_pow10"
}

// Return the number of decimal digits of `i`. Return `0` when `i==0`.
extern count-digitsstd/core/count-digits: (i : int) -> int( ii: int : intstd/core/int: V ) : intstd/core/int: V {
  cs "Primitive.IntCountDigits"
  js "_int_count_digits"
}

extern mul-exp10std/core/mul-exp10: (i : int, n : int) -> int( ii: int : intstd/core/int: V, nn: int : intstd/core/int: V ) : intstd/core/int: V {
  cs "Primitive.IntMulPow10"
  js "_int_mul_pow10"
}

extern cdiv-exp10std/core/cdiv-exp10: (i : int, n : int) -> int( ii: int : intstd/core/int: V, nn: int : intstd/core/int: V ) : intstd/core/int: V {
  cs "Primitive.IntCDivPow10"
  js "_int_cdiv_pow10"
}

fun cdivmod-exp10std/core/cdivmod-exp10: (i : int, n : int) -> (int, int)( ii: int : intstd/core/int: V, nn: int : intstd/core/int: V ) : (std/core/(,): (V, V) -> Vintstd/core/int: V,intstd/core/int: V)std/core/(,): (V, V) -> V {
  if (nstd/core/True: bool <=std/core/(<=).1: (int, int) -> bool 0) returnreturn: (int, int) (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)ii: int,0)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
  val cqcq: int = ii: int.cdiv-exp10std/core/cdiv-exp10: (i : int, n : int) -> int(nn: int)
  val crcr: int = ii: int -std/core/(-): (int, int) -> int cqcq: int.mul-exp10std/core/mul-exp10: (i : int, n : int) -> int(nn: int)
  (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)cqcq: int,crcr: int)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
}

fun divmod-exp10std/core/divmod-exp10: (i : int, n : int) -> (int, int)( ii: int : intstd/core/int: V, nn: int : intstd/core/int: V ) : (std/core/(,): (V, V) -> Vintstd/core/int: V,intstd/core/int: V)std/core/(,): (V, V) -> V {
  val (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)cqcq: int,crcr: int)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b) = cdivmod-exp10std/core/cdivmod-exp10: (i : int, n : int) -> (int, int)(ii: int,nn: int)
  if (!std/core/True: boolcrcr: int.neg?std/core/neg?.1: (i : int) -> bool) then (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)cqcq: int,crcr: int)std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b) else (std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)cqcq: int.decstd/core/dec: (i : int) -> int, crcr: int +std/core/(+): (int, int) -> int exp10std/core/exp10: (exp : int) -> int(nn: int))std/core/(,): forall<a,b> (fst : a, snd : b) -> (a, b)
}

// Is this an even integer?
fun even?std/core/even?: (i : int) -> bool(ii: int:intstd/core/int: V) : boolstd/core/bool: V { !std/core/(!): (bool) -> boolodd?std/core/odd?: (int) -> bool(ii: int) }

// Is the integer positive (stricly greater than zero)
fun pos?std/core/pos?.1: (i : int) -> bool(ii: int : intstd/core/int: V ) : boolstd/core/bool: V { ii: int.signstd/core/sign: (i : int) -> order ==std/core/(==).4: (x : order, y : order) -> bool Gtstd/core/Gt: order }

// Is the integer negative (stricly smaller than zero)
fun neg?std/core/neg?.1: (i : int) -> bool(ii: int : intstd/core/int: V ) : boolstd/core/bool: V { ii: int.signstd/core/sign: (i : int) -> order ==std/core/(==).4: (x : order, y : order) -> bool Ltstd/core/Lt: order }

extern inline signstd/core/sign: (i : int) -> order(i : intstd/core/int: V ) : orderstd/core/order: V {
  cs "Primitive.IntSign"
  js "$std_core._int_sign"
}

// Return the minimum of two integers
fun minstd/core/min: (i : int, j : int) -> int( ii: int : intstd/core/int: V, jj: int : intstd/core/int: V ) : intstd/core/int: V { if (istd/core/True: bool <=std/core/(<=).1: (int, int) -> bool jj: int) then ii: int else jj: int }

// Return the maximum of two integers
fun maxstd/core/max: (i : int, j : int) -> int( ii: int : intstd/core/int: V, jj: int : intstd/core/int: V ) : intstd/core/int: V { if (istd/core/True: bool >=std/core/(>=).1: (int, int) -> bool jj: int) then ii: int else jj: int }

// Returns the smallest element of a list of integers (or `default` (=`0`) for the empty list)
fun minimumstd/core/minimum: (xs : list<int>, default : ?int) -> int( xsxs: list<int> : liststd/core/list: V -> V<intstd/core/int: V>, defaultdefault: ?int : intstd/core/optional: V -> V = 0 ) : intstd/core/int: V
{
  match(xsxs: list<int>) {
    Nilstd/core/Nil: forall<a> list<a> -> defaultdefault: int
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: int,xxxx: list<int>) -> xxxx: list<int>.foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b( xx: int, minstd/core/min: (i : int, j : int) -> int )
  }
}

// Returns the largest element of a list of integers (or `default` (=`0`) for the empty list)
fun maximumstd/core/maximum: (xs : list<int>, default : ?int) -> int( xsxs: list<int> : liststd/core/list: V -> V<intstd/core/int: V>, defaultdefault: ?int : intstd/core/optional: V -> V = 0 ) : intstd/core/int: V
{
  match(xsxs: list<int>) {
    Nilstd/core/Nil: forall<a> list<a> -> defaultdefault: int
    Consstd/core/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: int,xxxx: list<int>) -> xxxx: list<int>.foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b( xx: int, maxstd/core/max: (i : int, j : int) -> int )
  }
}

// Return the sum of a list of integers
fun sumstd/core/sum: (xs : list<int>) -> int( xsxs: list<int> : liststd/core/list: V -> V<intstd/core/int: V> ) : intstd/core/int: V
{
  xsxs: list<int>.foldlstd/core/foldl: forall<a,b,e> (list<a>, b, (b, a) -> e b) -> e b( 0, fun(xx: int,yy: int) { xx: int +std/core/(+): (int, int) -> int yy: int } )
}

// Transform an integer to a maybe type, using `Nothing` for `0`
fun maybestd/core/maybe.7: (i : int) -> maybe<int>( ii: int : intstd/core/int: V ) : maybestd/core/maybe: V -> V<intstd/core/int: V> {
    if (istd/core/True: bool==std/core/(==).1: (int, int) -> bool0) then Nothingstd/core/Nothing: forall<a> maybe<a> else Juststd/core/Just: forall<a> (value : a) -> maybe<a>(ii: int)
}

// ----------------------------------------------------------------------------
// 32-bit integers
// Just define the operations needed for defining the std/core interface but
// don't export any definitions here. Full operations are defined in `std/int32`.
// ----------------------------------------------------------------------------

// Type of a 32-bit signed integer.
// See the [``std/int32``](std_int32.html) module for operations on 32-bit integers.
type int32std/core/int32: V

// Convert an `:int32` to an `:int`.
extern inline intstd/core/int: (i : int32) -> int( i : int32std/core/int32: V ) : intstd/core/int: V {
  cs inline "(new BigInteger(#1))"
  js "$std_core._int_double"
}

// Convert an integer to an `:int32`. The number is _clamped_ to the maximal or minimum `:int32`
// value if it is outside the range of an `:int32`.
extern inline int32std/core/int32: (int) -> int32  : (intstd/core/int: V) -> int32std/core/int32: V   {
  cs "Primitive.IntToInt32"
  js "$std_core._int_to_int32"
}


// Minimal set of operations that we need in `std/core`.
private extern inline (<=)std/core/(<=): (int32, int32) -> bool : (int32std/core/int32: V,int32std/core/int32: V) -> boolstd/core/bool: V  { inline "(#1 <= #2)"; js inline "(#1 <= #2)" }
private extern inline (<)std/core/(<): (int32, int32) -> bool  : (int32std/core/int32: V,int32std/core/int32: V) -> boolstd/core/bool: V  { inline "(#1 < #2)"; js inline "(#1 < #2)" }
private extern inline (+)std/core/(+): (int32, int32) -> int32  : (int32std/core/int32: V,int32std/core/int32: V) -> int32std/core/int32: V { inline "(#1 + #2)"; js inline "((#1 + #2)|0)" }
private extern inline (-)std/core/(-): (int32, int32) -> int32  : (int32std/core/int32: V,int32std/core/int32: V) -> int32std/core/int32: V { inline "(#1 - #2)"; js inline "((#1 - #2)|0)" }
private extern inline pos?std/core/pos?: (i : int32) -> bool( i : int32std/core/int32: V ) : boolstd/core/bool: V { inline "(#1>0)" }
private extern inline neg?std/core/neg?: (i : int32) -> bool( i : int32std/core/int32: V ) : boolstd/core/bool: V { inline "(#1<0)" }

private fun incrstd/core/incr: (i : int32) -> int32( ii: int32 : int32std/core/int32: V ) : int32std/core/int32: V {
  ii: int32 +std/core/(+).1: (int32, int32) -> int32 1.int32std/core/int32: (int) -> int32
}

private fun decrstd/core/decr: (i : int32) -> int32( ii: int32 : int32std/core/int32: V ) : int32std/core/int32: V {
  ii: int32 -std/core/(-).1: (int32, int32) -> int32 1.int32std/core/int32: (int) -> int32
}


// ----------------------------------------------------------------------------
// Parse numbers
// ----------------------------------------------------------------------------

// Parse an integer using `parseInt`. If an illegal digit character is encountered the
// `default` value is returned. An empty string will also result in `default`.
fun parse-int-defaultstd/core/parse-int-default: (s : string, default : ?int, hex : ?bool) -> int( ss: string : stringstd/core/string: V, defaultdefault: ?int : intstd/core/optional: V -> V = 0, hexhex: ?bool : boolstd/core/optional: V -> V = Falsestd/core/False: bool ) : intstd/core/int: V {
  if (sstd/core/True: bool.empty?std/core/empty?.1: (s : string) -> bool) then defaultdefault: int else ss: string.parse-intstd/core/parse-int: (s : string, hex : ?bool) -> maybe<int>(hexhex: bool).maybestd/core/maybe.3: forall<a> (m : maybe<a>, nothing : a) -> a(defaultdefault: int)
}

// Parse an integer after trimming whitespace.
// If an illegal digit character is encountered `Nothing` is returned.
// An empty string will result in `Just(0)`.
// A string can start with a `-` sign for negative numbers,
// and with `0x` or `0X` for hexadecimal numbers (in which case the `hex` parameter is ignored).
fun parse-intstd/core/parse-int: (s : string, hex : ?bool) -> maybe<int>( ss: string : stringstd/core/string: V, hexhex: ?bool : boolstd/core/optional: V -> V = Falsestd/core/False: bool) : maybestd/core/maybe: V -> V<intstd/core/int: V> {
  ss: string.trimstd/core/trim: (s : string) -> string.xparse-intstd/core/xparse-int: (s : string, hex : bool) -> maybe<int>(hexhex: bool)
}

private extern xparse-intstd/core/xparse-int: (s : string, hex : bool) -> maybe<int>( ss: string : stringstd/core/string: V, hexhex: bool : boolstd/core/bool: V ) : maybestd/core/maybe: V -> V<intstd/core/int: V> {
  cs "Primitive.IntParse"
  js "_int_parse"
}


// ----------------------------------------------------------------------------
// Doubles
// ----------------------------------------------------------------------------

extern inline (==)std/core/(==): (double, double) -> bool : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 == #2)"; js inline "(#1 === #2)" }
extern inline (!=)std/core/(!=): (double, double) -> bool : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 != #2)"; js inline "(#1 !== #2)" }
extern inline (<=)std/core/(<=): (double, double) -> bool : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 <= #2)" }
extern inline (>=)std/core/(>=): (double, double) -> bool : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 >= #2)" }
extern inline (<)std/core/(<): (double, double) -> bool  : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 < #2)" }
extern inline (>)std/core/(>): (double, double) -> bool  : (doublestd/core/double: V,doublestd/core/double: V) -> boolstd/core/bool: V  { inline "(#1 > #2)" }

extern inline (+)std/core/(+): (double, double) -> double : (doublestd/core/double: V,doublestd/core/double: V) -> doublestd/core/double: V { inline "(#1 + #2)" }
extern inline (-)std/core/(-): (double, double) -> double : (doublestd/core/double: V,doublestd/core/double: V) -> doublestd/core/double: V { inline "(#1 - #2)" }
extern inline (*)std/core/(*): (double, double) -> double : (doublestd/core/double: V,doublestd/core/double: V) -> doublestd/core/double: V { inline "(#1 * #2)" }
extern inline (/)std/core/(/): (double, double) -> double : (doublestd/core/double: V,doublestd/core/double: V) -> doublestd/core/double: V { inline "(#1 / #2)" }
extern inline (%)std/core/(%): (double, double) -> double : (doublestd/core/double: V,doublestd/core/double: V) -> doublestd/core/double: V { inline "(#1 % #2)" }

fun comparestd/core/compare.3: (x : double, y : double) -> order( xx: double : doublestd/core/double: V, yy: double : doublestd/core/double: V) : orderstd/core/order: V
{
  if (xstd/core/True: bool <std/core/(<).3: (double, double) -> bool yy: double) then Ltstd/core/Lt: order
  elif (xstd/core/True: bool >std/core/(>).2: (double, double) -> bool yy: double) then Gtstd/core/Gt: order
  else Eqstd/core/Eq: order
}


// Is the value negative?
fun neg?std/core/neg?.2: (d : double) -> bool( dd: double : doublestd/core/double: V ) : boolstd/core/bool: V {
  dd: double <std/core/(<).3: (double, double) -> bool 0.0
}

// Is the value positive?
fun pos?std/core/pos?.2: (d : double) -> bool( dd: double : doublestd/core/double: V ) : boolstd/core/bool: V {
  dd: double >std/core/(>).2: (double, double) -> bool 0.0
}

// Is the value zero?
fun zero?std/core/zero?.1: (d : double) -> bool( dd: double : doublestd/core/double: V ) : boolstd/core/bool: V {
  dd: double ==std/core/(==).2: (double, double) -> bool 0.0
}

fun signstd/core/sign.1: (d : double) -> order( dd: double : doublestd/core/double: V ) : orderstd/core/order: V {
  if (dstd/core/True: bool<std/core/(<).3: (double, double) -> bool0.0) then Ltstd/core/Lt: order elif (dstd/core/True: bool>std/core/(>).2: (double, double) -> bool0.0) then Gtstd/core/Gt: order else Eqstd/core/Eq: order
}

// Negate a `:double`.
extern inline (~)std/core/(~): (d : double) -> double(d : doublestd/core/double: V ) : doublestd/core/double: V {
  inline "(-#1)"  // inline so `~0.0` becomes negative zero
}


// convert a `:double` to an `:int` using `round` to round to its nearest integer.
// (rounding to an even number on a tie)
// Returns `0` if the argument is not `finite?`.
extern inline intstd/core/int: (d : double) -> int(d : doublestd/core/double: V ) : intstd/core/int: V {
  cs "Primitive.IntDouble"
  js "$std_core._int_double"
}


// Returns the value `d`  raised to the power `p` .
extern inline (^)std/core/(^): (d : double, p : double) -> double : (d:doublestd/core/double: V,p:doublestd/core/double: V) -> doublestd/core/double: V {
  cs "Math.Pow"
  js "Math.pow"
}

// Return the absolute value of a `:double` `d`
extern inline absstd/core/abs: (d : double) -> double : (d:doublestd/core/double: V) -> doublestd/core/double: V  {
  cs "Math.Abs"
  js "Math.abs"
}

// Returns the smallest of two doubles
fun minstd/core/min.1: (x : double, y : double) -> double( xx: double : doublestd/core/double: V, yy: double : doublestd/core/double: V ) : doublestd/core/double: V { if (xstd/core/True: bool <=std/core/(<=).3: (double, double) -> bool yy: double) then xx: double else yy: double }

// Returns the largest of two doubles
fun maxstd/core/max.1: (x : double, y : double) -> double( xx: double : doublestd/core/double: V, yy: double : doublestd/core/double: V ) : doublestd/core/double: V { if (xstd/core/True: bool >=std/core/(>=).2: (double, double) -> bool yy: double) then xx: double else yy: double }

// Returns the smallest element of a list of doubles (or `0` for the empty list)
fun minimumstd/core/minimum.1: (xs : list<double>) -> double( xsxs: list<double> : liststd/core/list: V -> V<doublestd/core/double: V> ) : doublestd/core/double: V
{
  match(xsxs: list<double>) {
    Nilstd/core