/*---------------------------------------------------------------------------
  Copyright 2026-2026, 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 `:result` functions.
module std/core/resultstd/core/result

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

// Convert a `:result` to a `:maybe` type discarding the value of the `Error` constructor
// and using `Just` for the `Ok` constructor.
pub fun maybestd/core/result/maybe: forall<a,b> (r : result<a,b>) -> maybe<a>( rr: result<$85,$86> : resultstd/core/types/result: (V, V) -> V<aa: V,ee: V> )result: -> total maybe<125> : maybestd/core/types/maybe: V -> V<aa: V>
  match rr: result<$85,$86>
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b> -> Nothingstd/core/types/Nothing: forall<a> maybe<a>
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $85) -> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $85)

// Convert a `:result` to its `Ok` value by providing a default value in the case of an `Error`.
pub fun defaultstd/core/result/default: forall<a,b> (r : result<a,b>, def : a) -> a( rr: result<$134,$135> : resultstd/core/types/result: (V, V) -> V<aa: V,ee: V>, defdef: $134 : aa: V )result: -> total 165 : astd/core/types/total: E
  match rr: result<$134,$135>
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b> -> defdef: $134
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $134) -> xx: $134

// Convert a `:result` to an `:eiter` type using `Left` for the `Error` constructor
// and using `Right` for the `Ok` constructor.
pub fun eitherstd/core/result/either: forall<a,b> (r : result<a,b>) -> either<b,a>( rr: result<$174,$175> : resultstd/core/types/result: (V, V) -> V<aa: V,ee: V> )result: -> total either<223,222> : eitherstd/core/types/either: (V, V) -> V<ee: V,aa: V>
  match rr: result<$174,$175>
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(xx: $175) -> Leftstd/core/types/Left: forall<a,b> (left : a) -> either<a,b>(xx: $175)
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $174)    -> Rightstd/core/types/Right: forall<a,b> (right : b) -> either<a,b>(xx: $174)

// Map over the `Ok` component of a `:result` type.
pub fun mapstd/core/result/map: forall<a,b,c,e> (e : result<a,b>, f : (a) -> e c) -> e result<c,b>( ee: result<$231,$232> : resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>, ff: ($231) -> $234 $233 : aa: V -> ee: E cc: V  )result: -> 293 result<292,291> : ee: E resultstd/core/types/result: (V, V) -> V<cc: V,bb: V>
  match ee: result<$231,$232>
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $231)    -> Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(ff: ($231) -> $234 $233(xx: $231))
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(xx: $232) -> Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(xx: $232)

// Flatten the result of a result.
pub fun flattenstd/core/result/flatten: forall<a,b,e> (rr : result<result<a,b>,b>) -> e result<a,b>( rrrr: result<result<$306,$307>,$307> : resultstd/core/types/result: (V, V) -> V<resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>,bb: V> )result: -> 385 result<383,384> : ee: E resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>
  match rrrr: result<result<$306,$307>,$307>
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(rr: result<$306,$307>) -> match rr: result<$306,$307>
      Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $306)    -> Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $306)
      Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(yy: $307) -> Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(yy: $307)
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(zz: $307)   -> Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(zz: $307)


// Equality on `:result` values
pub fun (==)std/core/result/(==): forall<a,b,e> (e1 : result<a,b>, e2 : result<a,b>, @implicit/ok/(==) : (a, a) -> e bool, @implicit/error/(==) : (b, b) -> e bool) -> e bool(e1e1: result<$395,$396>: resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>, e2e2: result<$395,$396>: resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>, (@implicit/ok/==)?ok/(==): ($395, $395) -> $397 bool: (aa: V, aa: V) -> ee: E boolstd/core/types/bool: V, (@implicit/error/==)?error/(==): ($396, $396) -> $397 bool: (bb: V, bb: V) -> ee: E boolstd/core/types/bool: V)result: -> 473 bool : ee: E boolstd/core/types/bool: V
  match e1e1: result<$395,$396>
    Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(l1l1: $396) -> match e2e2: result<$395,$396>
      Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(l2l2: $396) -> l1l1: $396 ==?error/(==): ($396, $396) -> $397 bool l2l2: $396
      _ -> Falsestd/core/types/False: bool
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(r1r1: $395) -> match e2e2: result<$395,$396>
      Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(r2r2: $395) -> r1r1: $395 ==?ok/(==): ($395, $395) -> $397 bool r2r2: $395
      _ -> Falsestd/core/types/False: bool

// Show an `:result` type
pub fun showstd/core/result/show: forall<a,b,e> (e : result<a,b>, @implicit/ok/show : (a) -> e string, @implicit/error/show : (b) -> e string) -> e string( ee: result<$488,$489> : resultstd/core/types/result: (V, V) -> V<aa: V,bb: V>, @implicit/ok/show?ok/show: ($488) -> $490 string : aa: V -> ee: E stringstd/core/types/string: V, @implicit/error/show?error/show: ($489) -> $490 string : bb: V -> ee: E stringstd/core/types/string: V )result: -> 574 string : ee: E stringstd/core/types/string: V
  match ee: result<$488,$489>
    Okstd/core/types/Ok: forall<a,b> (value : a) -> result<a,b>(xx: $488)    -> "Ok("literal: string
count= 3
++std/core/types/(++): (x : string, y : string) -> $490 string xx: $488.show?ok/show: ($488) -> $490 string ++std/core/types/(++): (x : string, y : string) -> $490 string ")"literal: string
count= 1
Errorstd/core/types/Error: forall<a,b> (error : b) -> result<a,b>(yy: $489) -> "Error("literal: string
count= 6
++std/core/types/(++): (x : string, y : string) -> $490 string yy: $489.show?error/show: ($489) -> $490 string ++std/core/types/(++): (x : string, y : string) -> $490 string ")"literal: string
count= 1