/*---------------------------------------------------------------------------
  Copyright 2012-2024, Microsoft Research, Daan Leijen.

  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 LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

// Standard `:maybe2` functions which, unlike `:maybe`, can contain 2 values to avoid boxing allocations.
module std/core/maybe2std/core/maybe2

import std/core/typesstd/core/types
import std/core/hndstd/core/hnd
import std/core/exnstd/core/exn

// Match a `:maybe2` value and either return a default value on `Nothing2` or apply a function to the value on `Just2`
pub fun maybe2std/core/maybe2/maybe2: forall<a,b,c,e> (m : maybe2<a,b>, onNothing : c, onJust : (a, b) -> e c) -> e c( mm: maybe2<$124,$125> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, onNothingonNothing: $126: cc: V, onJustonJust: ($124, $125) -> $127 $126: (aa: V,bb: V) -> ee: E cc: V )result: -> 168 167 : ee: E cc: V
  match mm: maybe2<$124,$125>
    Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b>   -> onNothingonNothing: $126
    Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $124,yy: $125) -> onJustonJust: ($124, $125) -> $127 $126(xx: $124,yy: $125)

// Convert a `:maybe2<a,b>` value to `:(a,b)`, using the `nothing` parameter for `Nothing2`.
pub fun defaultstd/core/maybe2/default: forall<a,b> (m : maybe2<a,b>, nothing : (a, b)) -> (a, b)( mm: maybe2<$181,$182> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, nothingnothing: ($181, $182) : (std/core/types/tuple2: (V, V) -> Vaa: V,bb: V) )result: -> total (221, 222) : (std/core/types/tuple2: (V, V) -> Vaa: V,bb: V)
  match mm: maybe2<$181,$182>
    Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b>   -> nothingnothing: ($181, $182)
    Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $181,yy: $182) -> (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)xx: $181,yy: $182)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)

// Get the value of the `Just` constructor or raise an exception
pub fun unjuststd/core/maybe2/unjust: forall<a,b> (m : maybe2<a,b>, @implicit/kk-file-line : string) -> exn (a, b)( mm: maybe2<$230,$231> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, @implicit/kk-file-line?kk-file-line: string: stringstd/core/types/string: V)result: -> exn (288, 289) : exnstd/core/exn/exn: (E, V) -> V (std/core/types/tuple2: (V, V) -> Vaa: V,bb: V)
  match mm: maybe2<$230,$231>
    Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $230,yy: $231) -> (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)xx: $230,yy: $231)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)
    Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b>   -> throwstd/core/exn/throw: (message : string, info : ? exception-info) -> exn ($230, $231)("unexpected Nothing2 in "literal: string
count= 23
++std/core/types/(++): (x : string, y : string) -> exn string @implicit/kk-file-line?kk-file-line: string
) // Get the value of the `Just` constructor or raise an exception pub fun expectstd/core/maybe2/expect: forall<a,b> (m : maybe2<a,b>, error-msg : string) -> exn (a, b)( mm: maybe2<$297,$298> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, error-msgerror-msg: string: stringstd/core/types/string: V)result: -> exn (347, 348) : exnstd/core/exn/exn: (E, V) -> V (std/core/types/tuple2: (V, V) -> Vaa: V,bb: V) match mm: maybe2<$297,$298> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $297,yy: $298) -> (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)xx: $297,yy: $298)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> throwstd/core/exn/throw: (message : string, info : ? exception-info) -> exn ($297, $298)(error-msgerror-msg: string) pub fun mapstd/core/maybe2/map: forall<a,b,c,d,e> (m : maybe2<a,b>, f : (a, b) -> e (c, d)) -> e maybe2<c,d>( mm: maybe2<$356,$357> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, ff: ($356, $357) -> $360 ($358, $359) : (aa: V,bb: V) -> ee: E (std/core/types/tuple2: (V, V) -> Vcc: V,dd: V) )result: -> 429 maybe2<427,428> : ee: E maybe2std/core/types/maybe2: (V, V) -> V<cc: V,dd: V> match mm: maybe2<$356,$357> Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $356,yy: $357) -> match ff: ($356, $357) -> $360 ($358, $359)(xx: $356,yy: $357) (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)fxfx: $358,fyfy: $359)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) -> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(fxfx: $358,fyfy: $359) pub fun (||)std/core/maybe2/(||): forall<a,b> (m1 : maybe2<a,b>, m2 : maybe2<a,b>) -> maybe2<a,b>( m1m1: maybe2<$445,$446> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, m2m2: maybe2<$445,$446>: maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V> )result: -> total maybe2<469,470> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V> match m1m1: maybe2<$445,$446> Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> m2m2: maybe2<$445,$446> _ -> m1m1: maybe2<$445,$446> // Equality on `:maybe` pub fun (==)std/core/maybe2/(==): forall<a,b,e> (mb1 : maybe2<a,b>, mb2 : maybe2<a,b>, @implicit/fst/(==) : (a, a) -> e bool, @implicit/snd/(==) : (b, b) -> e bool) -> e bool( mb1mb1: maybe2<$478,$479> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, mb2mb2: maybe2<$478,$479> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, (@implicit/fst/==)?fst/(==): ($478, $478) -> $480 bool : (aa: V,aa: V) -> ee: E boolstd/core/types/bool: V, (@implicit/snd/==)?snd/(==): ($479, $479) -> $480 bool : (bb: V,bb: V) -> ee: E boolstd/core/types/bool: V )result: -> 569 bool : ee: E boolstd/core/types/bool: V match mb1mb1: maybe2<$478,$479> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $478,yy: $479) -> match mb2mb2: maybe2<$478,$479> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(aa: $478,bb: $479) -> (xx: $478==?fst/(==): ($478, $478) -> $480 boolaa: $478) &&std/core/types/(&&): (x : bool, y : bool) -> $480 bool (yy: $479==?snd/(==): ($479, $479) -> $480 boolbb: $479) Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Falsestd/core/types/False: bool Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> match mb2mb2: maybe2<$478,$479> Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Truestd/core/types/True: bool _ -> Falsestd/core/types/False: bool // Order on `:maybe` values pub fun cmpstd/core/maybe2/cmp: forall<a,b,e> (mb1 : maybe2<a,b>, mb2 : maybe2<a,b>, @implicit/fst/cmp : (a, a) -> e order, @implicit/snd/cmp : (b, b) -> e order) -> e order( mb1mb1: maybe2<$584,$585> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, mb2mb2: maybe2<$584,$585> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, @implicit/fst/cmp?fst/cmp: ($584, $584) -> $586 order : (aa: V,aa: V) -> ee: E orderstd/core/types/order: V, @implicit/snd/cmp?snd/cmp: ($585, $585) -> $586 order : (bb: V,bb: V) -> ee: E orderstd/core/types/order: V)result: -> 657 order : ee: E orderstd/core/types/order: V match mb1mb1: maybe2<$584,$585> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $584,yy: $585) -> match mb2mb2: maybe2<$584,$585> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(aa: $584,bb: $585) -> match @implicit/fst/cmp?fst/cmp: ($584, $584) -> $586 order(xx: $584,aa: $584) Eqstd/core/types/Eq: order -> @implicit/snd/cmp?snd/cmp: ($585, $585) -> $586 order(yy: $585,bb: $585) lglg: order -> lglg: order Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Gtstd/core/types/Gt: order Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> match mb2mb2: maybe2<$584,$585> Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Eqstd/core/types/Eq: order _ -> Ltstd/core/types/Lt: order // Show a `:maybe2` type pub fun showstd/core/maybe2/show: forall<a,b,e> (mb : maybe2<a,b>, @implicit/fst/show : (a) -> e string, @implicit/snd/show : (b) -> e string) -> e string( mbmb: maybe2<$667,$668> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V>, @implicit/fst/show?fst/show: ($667) -> $669 string : aa: V -> ee: E stringstd/core/types/string: V, @implicit/snd/show?snd/show: ($668) -> $669 string : bb: V -> ee: E stringstd/core/types/string: V )result: -> 754 string : ee: E stringstd/core/types/string: V match mbmb: maybe2<$667,$668> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b>(xx: $667,yy: $668) -> "Just2("literal: string
count= 6
++std/core/types/(++): (x : string, y : string) -> $669 string xx: $667.show?fst/show: ($667) -> $669 string ++std/core/types/(++): (x : string, y : string) -> $669 string ","literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> $669 string yy: $668.show?snd/show: ($668) -> $669 string ++std/core/types/(++): (x : string, y : string) -> $669 string ")"literal: string
count= 1
Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> "Nothing2"literal: string
count= 8
// Convert a `:maybe2` type to a boolean, equivalent to `is-just2`. pub fun boolstd/core/maybe2/bool: forall<a,b> (mb : maybe2<a,b>) -> bool( mbmb: maybe2<$773,$774> : maybe2std/core/types/maybe2: (V, V) -> V<aa: V,bb: V> )result: -> total bool : boolstd/core/types/bool: V match mbmb: maybe2<$773,$774> Just2std/core/types/Just2: forall<a,b> (fst : a, snd : b) -> maybe2<a,b> -> Truestd/core/types/True: bool Nothing2std/core/types/Nothing2: forall<a,b> maybe2<a,b> -> Falsestd/core/types/False: bool