/*---------------------------------------------------------------------------
  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 `:maybe` functions.
module std/core/maybestd/core/maybe

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

// Match a `:maybe` value and either return a default value on `Nothing` or apply a function to the value on `Just`
pub fun maybestd/core/maybe/maybe: forall<a,b,e> (m : maybe<a>, onNothing : b, onJust : (a) -> e b) -> e b( mm: maybe<$153> : maybestd/core/types/maybe: V -> V<aa: V>, onNothingonNothing: $154: bb: V, onJustonJust: ($153) -> $155 $154: aa: V -> ee: E bb: V )result: -> 175 174 : ee: E bb: V
  match mm: maybe<$153>
    Nothingstd/core/types/Nothing: forall<a> maybe<a> -> onNothingonNothing: $154
    Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $153) -> onJustonJust: ($153) -> $155 $154(xx: $153)

// Convert a `:maybe<a>` value to `:a`, using the `nothing` parameter for `Nothing`.
pub fun defaultstd/core/maybe/default: forall<a> (m : maybe<a>, nothing : a) -> a( mm: maybe<$94> : maybestd/core/types/maybe: V -> V<aa: V>, nothingnothing: $94 : aa: V )result: -> total 108 : astd/core/types/total: E
  match mm: maybe<$94>
    Nothingstd/core/types/Nothing: forall<a> maybe<a> -> nothingnothing: $94
    Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $94) -> xx: $94

// Get the value of the `Just` constructor or raise an exception
pub fun unjuststd/core/maybe/unjust: forall<a> (m : maybe<a>) -> exn a( mm: maybe<$185> : maybestd/core/types/maybe: V -> V<aa: V> )result: -> exn 208 : exnstd/core/exn/exn: (E, V) -> V aa: V
  match mm: maybe<$185>
    Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $185) -> xx: $185
    Nothingstd/core/types/Nothing: forall<a> maybe<a> -> throwstd/core/exn/throw: (message : string, info : ? exception-info) -> exn $185("unexpected Nothing in std/core/maybe/unjust"literal: string
count= 43
) pub fun mapstd/core/maybe/map: forall<a,b,e> (m : maybe<a>, f : (a) -> e b) -> e maybe<b>( mm: maybe<$113> : maybestd/core/types/maybe: V -> V<aa: V>, ff: ($113) -> $115 $114 : aa: V -> ee: E bb: V )result: -> 143 maybe<142> : ee: E maybestd/core/types/maybe: V -> V<bb: V> match mm: maybe<$113> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Nothingstd/core/types/Nothing: forall<a> maybe<a> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $113) -> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(ff: ($113) -> $115 $114(xx: $113)) pub fun (||)std/core/maybe/(||): forall<a> (m1 : maybe<a>, m2 : maybe<a>) -> maybe<a>( m1m1: maybe<$213> : maybestd/core/types/maybe: V -> V<aa: V>, m2m2: maybe<$213>: maybestd/core/types/maybe: V -> V<aa: V> )result: -> total maybe<225> : maybestd/core/types/maybe: V -> V<aa: V> match m1m1: maybe<$213> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> m2m2: maybe<$213> _ -> m1m1: maybe<$213> // Equality on `:maybe` pub fun (==)std/core/maybe/(==): forall<a> (mb1 : maybe<a>, mb2 : maybe<a>, @implicit/(==) : (a, a) -> bool) -> bool( mb1mb1: maybe<$230> : maybestd/core/types/maybe: V -> V<aa: V>, mb2mb2: maybe<$230> : maybestd/core/types/maybe: V -> V<aa: V>, (@implicit/==)?(==): ($230, $230) -> bool : (aa: V,aa: V) -> boolstd/core/types/bool: V )result: -> total bool : boolstd/core/types/bool: V match mb1mb1: maybe<$230> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $230) -> match mb2mb2: maybe<$230> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(yy: $230) -> xx: $230==?(==): ($230, $230) -> boolyy: $230 Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Falsestd/core/types/False: bool Nothingstd/core/types/Nothing: forall<a> maybe<a> -> match mb2mb2: maybe<$230> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Truestd/core/types/True: bool _ -> Falsestd/core/types/False: bool // Order on `:maybe` values pub fun cmpstd/core/maybe/cmp: forall<a> (mb1 : maybe<a>, mb2 : maybe<a>, @implicit/cmp : (a, a) -> order) -> order( mb1mb1: maybe<$275> : maybestd/core/types/maybe: V -> V<aa: V>, mb2mb2: maybe<$275> : maybestd/core/types/maybe: V -> V<aa: V>, @implicit/cmp?cmp: ($275, $275) -> order : (aa: V,aa: V) -> orderstd/core/types/order: V )result: -> total order : orderstd/core/types/order: V match mb1mb1: maybe<$275> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $275) -> match mb2mb2: maybe<$275> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(yy: $275) -> cmp?cmp: ($275, $275) -> order(xx: $275,yy: $275) Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Gtstd/core/types/Gt: order Nothingstd/core/types/Nothing: forall<a> maybe<a> -> match mb2mb2: maybe<$275> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Eqstd/core/types/Eq: order _ -> Ltstd/core/types/Lt: order // Order two `:maybe` values in ascending order pub fip fun order2std/core/maybe/order2: forall<a> (mb1 : maybe<a>, mb2 : maybe<a>, @implicit/order2 : (a, a) -> order2<a>) -> order2<maybe<a>>( mb1mb1: maybe<$316> : maybestd/core/types/maybe: V -> V<aa: V>, mb2mb2: maybe<$316> : maybestd/core/types/maybe: V -> V<aa: V>, ^@implicit/order2?order2: ($316, $316) -> order2<$316> : (aa: V,aa: V) -> order2std/core/types/order2: V -> V<aa: V> )result: -> total order2<maybe<433>> : order2std/core/types/order2: V -> V<maybestd/core/types/maybe: V -> V<aa: V>> match mb1mb1: maybe<$316> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $316) -> match mb2mb2: maybe<$316> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(yy: $316) -> match order2?order2: ($316, $316) -> order2<$316>(xx: $316,yy: $316) Eq2std/core/types/Eq2: forall<a> (eq : a) -> order2<a>(zz: $316) -> Eq2std/core/types/Eq2: forall<a> (eq : a) -> order2<a>(Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(zz: $316)) Lt2std/core/types/Lt2: forall<a> (lt : a, gt : a) -> order2<a>(ll: $316,gg: $316) -> Lt2std/core/types/Lt2: forall<a> (lt : a, gt : a) -> order2<a>(Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(ll: $316),Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(gg: $316)) Gt2std/core/types/Gt2: forall<a> (lt : a, gt : a) -> order2<a>(ll: $316,gg: $316) -> Gt2std/core/types/Gt2: forall<a> (lt : a, gt : a) -> order2<a>(Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(ll: $316),Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(gg: $316)) Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Gt2std/core/types/Gt2: forall<a> (lt : a, gt : a) -> order2<a>(Nothingstd/core/types/Nothing: forall<a> maybe<a>,Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $316)) Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Lt2std/core/types/Lt2: forall<a> (lt : a, gt : a) -> order2<a>(Nothingstd/core/types/Nothing: forall<a> maybe<a>,mb2mb2: maybe<$316>) // Show a `:maybe` type pub fun showstd/core/maybe/show: forall<a,e> (mb : maybe<a>, @implicit/show : (a) -> e string) -> e string( mbmb: maybe<$438> : maybestd/core/types/maybe: V -> V<aa: V>, @implicit/show?show: ($438) -> $439 string : aa: V -> ee: E stringstd/core/types/string: V )result: -> 484 string : ee: E stringstd/core/types/string: V match mbmb: maybe<$438> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $438) -> "Just("literal: string
count= 5
++std/core/types/(++): (x : string, y : string) -> $439 string xx: $438.show?show: ($438) -> $439 string ++std/core/types/(++): (x : string, y : string) -> $439 string ")"literal: string
count= 1
Nothingstd/core/types/Nothing: forall<a> maybe<a> -> "Nothing"literal: string
count= 7
// Convert a maybe type to a boolean, equivalent to `is-just`. pub fun boolstd/core/maybe/bool: forall<a> (mb : maybe<a>) -> bool( mbmb: maybe<$75> : maybestd/core/types/maybe: V -> V<aa: V> )result: -> total bool : boolstd/core/types/bool: V match mbmb: maybe<$75> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a> -> Truestd/core/types/True: bool Nothingstd/core/types/Nothing: forall<a> maybe<a> -> Falsestd/core/types/False: bool