either

A MoonBit library providing the Either type for representing values with two possible types, inspired by Rust's either and Haskell's either libraries.

Utility
Either
moon add Kaida-Amethyst/either@0.1.3
Download zip
Version
0.1.3
License
Apache-2.0
Last updated
2 days ago
Downloads
1K
README

#Either

A MoonBit library providing the Either type for representing values with two possible types, inspired by Rust's either library and Haskell's either library.

The Either type is a simple but powerful sum type that can hold one of two possible values: Left(L) or Right(R). It's commonly used for error handling, representing success/failure scenarios, or any situation where you need to choose between two alternative types.

#Basic Usage

#Creating Either Values

test "creating either values" {
// Create Left and Right values
let left_val : Either[Int, String] = left(42)
let right_val : Either[Int, String] = right("hello")

// Using constructors directly
let left_direct : Either[Int, Unit] = Left(42)
let right_direct : Either[Unit, String] = Right("hello")

assert_true(left_val is Left(42))
assert_true(right_val is Right("hello"))
assert_true(left_direct is Left(42))
assert_true(right_direct is Right("hello"))
}

#Checking Either Variants

test "checking variants" {
let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]

// Using is_left() and is_right()
assert_true(values[0].is_left())
assert_true(values[1].is_right())
assert_false(values[2].is_right())

// Using pattern matching with `is` (preferred)
assert_true(values[0] is Left(_))
assert_true(values[1] is Right(_))
assert_false(values[2] is Right(_))
}

#Extracting Values

test "extracting values" {
let left_val : Either[Int, String] = Either::Left(42)
let right_val : Either[Int, String] = Either::Right("hello")

// Extract as Option
assert_true(left_val.left() is Some(42))
assert_true(left_val.right() is None)
assert_true(right_val.right() is Some("hello"))
assert_true(right_val.left() is None)

// Extract with default values
assert_eq(left_val.left_or(0), 42)
assert_eq(left_val.right_or("default"), "default")
assert_eq(right_val.left_or(0), 0)
assert_eq(right_val.right_or("default"), "hello")
}

#Transformations

#Mapping Operations

test "mapping operations" {
let left : Either[Int, String] = Left(10)
let right : Either[Int, String] = Right("hello")

// Map left side only
let mapped_left = left.map_left(x => x * 2)
assert_true(mapped_left is Left(20))

// Map right side only
let mapped_right = right.map_right(s => s + " world")
assert_true(mapped_right is Right("hello world"))

// Map both sides (bimap)
let bimapped = left.map_either(x => x * 2, s => s + " world")
assert_true(bimapped is Left(20))
}

#Type Conversions

test "type conversions" {
// From Option
let some_val: Int? = Some(42)
let none_val: Int? = None

let either_from_some = from_option_left_or(some_val, "default")
assert_true(either_from_some is Left(42))

let either_from_none = from_option_left_or(none_val, "default")
assert_true(either_from_none is Right("default"))

// From Result
let ok_result: Result[String, Int] = Ok("success")
let err_result: Result[String, Int] = Err(404)

let either_ok = from_result(ok_result)
assert_true(either_ok is Right("success"))

let either_err = from_result(err_result)
assert_true(either_err is Left(404))

// To Result
let left_either : Either[Int, String] = Left(404)
let result_from_either = left_either.to_result()
assert_true(result_from_either is Err(404))
}

#Utility Operations

test "utility operations" {
let left : Either[Int, String] = Left(42)
let right : Either[Int, String] = Right("hello")

// Flip Left and Right
assert_true(left.flip() is Right(42))
assert_true(right.flip() is Left("hello"))

// Expect operations (abort on wrong variant)
assert_eq(left.expect_left("Expected left"), 42)
assert_eq(right.expect_right("Expected right"), "hello")

// Or else operations with lazy evaluation
let computed_left = right.left_or_else(() => 100)
assert_eq(computed_left, 100)

let computed_right = left.right_or_else(() => "computed")
assert_eq(computed_right, "computed")
}

#Advanced Usage

test "advanced usage" {
// Chain operations
let result = Left(5)
|> Either::map_left(x => x * 2) // Left(10)
|> Either::map_right(x => x + 1) // Still Left(10)
|> Either::flip() // Right(10)
|> Either::map_right(x => x + 5) // Right(15)

assert_true(result is Right(15))

// Combining with control flow
let values: Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
let lefts = []
let rights = []

for either in values {
match either {
Either::Left(x) => lefts.push(x)
Either::Right(s) => rights.push(s)
}
}

assert_eq(lefts, [1, 3])
assert_eq(rights, ["two"])
}

#API Reference

The library provides comprehensive functionality for working with Either values:

  • Constructors: left(), right()
  • Type checks: is_left(), is_right()
  • Value extraction: left(), right(), left_or(), right_or(), left_or_else(), right_or_else()
  • Safe unwrapping: expect_left(), expect_right(), left_unwrap(), right_unwrap()
  • Transformations: map_left(), map_right(), map_either(), flip()
  • Case analysis: either()
  • Conversions: from_option_*(), from_result(), to_result()

This library makes it easy to work with sum types in a functional programming style, providing a robust foundation for representing alternative outcomes.


#Either (中文版)

一个 MoonBit 库,提供 Either 类型,用于表示具有两种可能类型的值,其灵感来源于 Rust 的 either 库和 Haskell 的 either 库。

Either 类型是一个简单但功能强大的和类型,可以容纳两个可能值之一:Left(L)Right(R)。它通常用于任何需要在两种备选类型之间进行选择的情况。

#基本用法

#创建 Either 值

test "creating either values" {
// 创建 Left 和 Right 值
let left_val : Either[Int, String] = left(42)
let right_val : Either[Int, String] = right("hello")

// 直接使用构造函数
let left_direct : Either[Int, Unit] = Left(42)
let right_direct : Either[Unit, String] = Right("hello")

assert_true(left_val is Left(42))
assert_true(right_val is Right("hello"))
assert_true(left_direct is Left(42))
assert_true(right_direct is Right("hello"))
}

#检查 Either 变体

test "checking variants" {
let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]

// 使用 is_left() 和 is_right()
assert_true(values[0].is_left())
assert_true(values[1].is_right())
assert_false(values[2].is_right())

// 使用 `is` 进行模式匹配 (首选)
assert_true(values[0] is Left(_))
assert_true(values[1] is Right(_))
assert_false(values[2] is Right(_))
}

#提取值

test "extracting values" {
let left_val : Either[Int, String] = Either::Left(42)
let right_val : Either[Int, String] = Either::Right("hello")

// 提取为 Option
assert_true(left_val.left() is Some(42))
assert_true(left_val.right() is None)
assert_true(right_val.right() is Some("hello"))
assert_true(right_val.left() is None)

// 使用默认值提取
assert_eq(left_val.left_or(0), 42)
assert_eq(left_val.right_or("default"), "default")
assert_eq(right_val.left_or(0), 0)
assert_eq(right_val.right_or("default"), "hello")
}

#转换

#映射操作

test "mapping operations" {
let left : Either[Int, String] = Left(10)
let right : Either[Int, String] = Right("hello")

// 只映射 left
let mapped_left = left.map_left(x => x * 2)
assert_true(mapped_left is Left(20))

// 只映射 right
let mapped_right = right.map_right(s => s + " world")
assert_true(mapped_right is Right("hello world"))

// 映射两边 (bimap)
let bimapped = left.map_either(x => x * 2, s => s + " world")
assert_true(bimapped is Left(20))
}

#类型转换

test "type conversions" {
// 从 Option
let some_val: Int? = Some(42)
let none_val: Int? = None

let either_from_some = from_option_left_or(some_val, "default")
assert_true(either_from_some is Left(42))

let either_from_none = from_option_left_or(none_val, "default")
assert_true(either_from_none is Right("default"))

// 从 Result
let ok_result: Result[String, Int] = Ok("success")
let err_result: Result[String, Int] = Err(404)

let either_ok = from_result(ok_result)
assert_true(either_ok is Right("success"))

let either_err = from_result(err_result)
assert_true(either_err is Left(404))

// 转换为 Result
let left_either : Either[Int, String] = Left(404)
let result_from_either = left_either.to_result()
assert_true(result_from_either is Err(404))
}

#实用操作

test "utility operations" {
let left : Either[Int, String] = Left(42)
let right : Either[Int, String] = Right("hello")

// 翻转 Left 和 Right
assert_true(left.flip() is Right(42))
assert_true(right.flip() is Left("hello"))

// Expect 操作 (在错误的变体上会中止)
assert_eq(left.expect_left("Expected left"), 42)
assert_eq(right.expect_right("Expected right"), "hello")

// 使用惰性求值的 or_else 操作
let computed_left = right.left_or_else(() => 100)
assert_eq(computed_left, 100)

let computed_right = left.right_or_else(() => "computed")
assert_eq(computed_right, "computed")
}

#高级用法

test "advanced usage" {
// 链式操作
let result = Left(5)
|> Either::map_left(x => x * 2) // Left(10)
|> Either::map_right(x => x + 1) // 仍然是 Left(10)
|> Either::flip() // Right(10)
|> Either::map_right(x => x + 5) // Right(15)

assert_true(result is Right(15))

// 与控制流结合
let values: Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
let lefts = []
let rights = []

for either in values {
match either {
Either::Left(x) => lefts.push(x)
Either::Right(s) => rights.push(s)
}
}

assert_eq(lefts, [1, 3])
assert_eq(rights, ["two"])
}

#API 参考

该库为使用 Either 值提供了全面的功能:

  • 构造函数: left(), right()
  • 类型检查: is_left(), is_right()
  • 值提取: left(), right(), left_or(), right_or(), left_or_else(), right_or_else()
  • 安全解包: expect_left(), expect_right(), left_unwrap(), right_unwrap()
  • 转换: map_left(), map_right(), map_either(), flip()
  • 情况分析: either()
  • 转换: from_option_*(), from_result(), to_result()

该库使以函数式编程风格使用和类型变得容易,为表示备选结果提供了坚实的基础。

#
Either

pub(all) enum Either[L, R] {
Left(L)
Right(R)
}

Inspired by Haskell's Either and Rust's either library, this enum represents a value that can be one of two types.
impl Eq for Either[L, R]
impl Hash for Either[L, R]
impl Show for Either[L, R]

#
Either::either

fn[L, R, T] Either::either(self : Either[L, R], fl : (L) -> T raise?, fr : (R) -> T raise?) -> T raise?

Case analysis for Either. Applies the first function to Left values and the second function to Right values, returning the result.

let left : Either[Int, String] = Left(42)
let result1 = left.either(x => x * 2, s => s.length())
assert_eq(result1, 84)

let right : Either[Int, String] = Right("hello")
let result2 = right.either(x => x * 2, s => s.length())
assert_eq(result2, 5)

#
Either::expect_left

fn[L, R] Either::expect_left(self : Either[L, R], msg : String) -> L

Returns the Left value if present, otherwise aborts with the provided message.

let left_value: Either[Int, String] = Left(42)
let unwrapped = left_value.expect_left("Expected left value")
assert_eq(unwrapped, 42)

#
Either::expect_right

fn[L, R] Either::expect_right(self : Either[L, R], msg : String) -> R

Returns the Right value if present, otherwise aborts with the provided message.

let right_value: Either[Int, String] = Right("hello")
let unwrapped = right_value.expect_right("Expected right value")
assert_eq(unwrapped, "hello")

#
Either::factor_err

fn[L, R, E] Either::factor_err(self : Either[Result[L, E], Result[R, E]]) -> Result[Either[L, R], E]

Factors out error values from an Either containing Results with the same error type. If either side is an Err, returns Err with that error. Otherwise, returns Ok with the Either containing the unwrapped values.

let left_ok : Either[Result[Int, String], Result[Bool, String]] = Left(Ok(42))
let result1 = left_ok.factor_err()
assert_true(result1 is Ok(Left(42)))

let left_err : Either[Result[Int, String], Result[Bool, String]] = Left(Err("error"))
let result2 = left_err.factor_err()
assert_true(result2 is Err("error"))

let right_ok : Either[Result[Int, String], Result[Bool, String]] = Right(Ok(true))
let result3 = right_ok.factor_err()
assert_true(result3 is Ok(Right(true)))

#
Either::factor_first

fn[T, L, R] Either::factor_first(self : Either[(T, L), (T, R)]) -> (T, Either[L, R])

Factors out the first element from an Either containing tuples with the same first type. Returns a tuple with the common first element and an Either containing the second elements.

let left_pair : Either[(Int, String), (Int, Bool)] = Left((42, "hello"))
let result1 = left_pair.factor_first()
assert_eq(result1.0, 42)
assert_true(result1.1 is Left("hello"))

let right_pair : Either[(Int, String), (Int, Bool)] = Right((42, true))
let result2 = right_pair.factor_first()
assert_eq(result2.0, 42)
assert_true(result2.1 is Right(true))

#
Either::factor_none

fn[L, R] Either::factor_none(self : Either[L?, R?]) -> Either[L, R]?

Factors out None values from an Either containing Options. If either side is None, returns None. Otherwise, returns Some with the Either containing the unwrapped values.

let left_some : Either[Int?, String?] = Left(Some(42))
let result1 = left_some.factor_none()
assert_true(result1 is Some(Left(42)))

let left_none : Either[Int?, String?] = Left(None)
let result2 = left_none.factor_none()
assert_true(result2 is None)

let right_some : Either[Int?, String?] = Right(Some("hello"))
let result3 = right_some.factor_none()
assert_true(result3 is Some(Right("hello")))

#
Either::factor_ok

fn[T, L, R] Either::factor_ok(self : Either[Result[T, L], Result[T, R]]) -> Result[T, Either[L, R]]

Factors out Ok values from an Either containing Results with the same Ok type. If either side is Ok, returns Ok with that value. Otherwise, returns Err with Either containing the error values.

let left_ok : Either[Result[Int, String], Result[Int, Bool]] = Left(Ok(42))
let result1 = left_ok.factor_ok()
assert_true(result1 is Ok(42))

let left_err : Either[Result[Int, String], Result[Int, Bool]] = Left(Err("error"))
let result2 = left_err.factor_ok()
assert_true(result2 is Err(Left("error")))

let right_err : Either[Result[Int, String], Result[Int, Bool]] = Right(Err(false))
let result3 = right_err.factor_ok()
assert_true(result3 is Err(Right(false)))

#
Either::factor_second

fn[T, L, R] Either::factor_second(self : Either[(L, T), (R, T)]) -> (Either[L, R], T)

Factors out the second element from an Either containing tuples with the same second type. Returns a tuple with an Either containing the first elements and the common second element.

let left_pair : Either[(String, Int), (Bool, Int)] = Left(("hello", 42))
let result1 = left_pair.factor_second()
assert_true(result1.0 is Left("hello"))
assert_eq(result1.1, 42)

let right_pair : Either[(String, Int), (Bool, Int)] = Right((true, 42))
let result2 = right_pair.factor_second()
assert_true(result2.0 is Right(true))
assert_eq(result2.1, 42)

#
Either::flip

fn[L, R] Either::flip(self : Either[L, R]) -> Either[R, L]

Convert Either[L, R] to Either[R, L].

let left : Either[Int, Unit] = Left(123)
assert_true(left.flip() is Right(123))

let right : Either[Unit, String] = Right("hello")
assert_true(right.flip() is Left("hello"))

#
Either::is_left

fn[L, R] Either::is_left(self : Either[L, R]) -> Bool

Returns true if the Either is a Left variant.

let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
assert_true(values[0].is_left())
assert_false(values[1].is_left())
assert_true(values[2].is_left())

// Note: use `is` may be better.
assert_true(values[0] is Left(_))
assert_false(values[1] is Left(_))
assert_true(values[2] is Left(_))

#
Either::is_right

fn[L, R] Either::is_right(self : Either[L, R]) -> Bool

Returns true if the Either is a Right variant.

let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
assert_false(values[0].is_right())
assert_true(values[1].is_right())
assert_false(values[2].is_right())

// Note: use `is` may be better.
assert_false(values[0] is Right(_))
assert_true(values[1] is Right(_))
assert_false(values[2] is Right(_))

#
Either::left

fn[L, R] Either::left(self : Either[L, R]) -> L?

Convert the left side of Either[L, R] to an Option[L].

let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
assert_true(values[0].left() is Some(_))
assert_true(values[1].left() is None)
assert_true(values[2].left() is Some(_))

#
Either::left_and_then

fn[L, R, S] Either::left_and_then(self : Either[L, R], f : (L) -> Either[S, R] raise?) -> Either[S, R] raise?

Applies a function to the Left value if present, returning the result. If the Either is Right, returns the Right value unchanged. This is a monadic bind operation for the Left side.

let left : Either[Int, String] = Left(5)
let result = left.left_and_then(x => if x > 0 { Left(x * 2) } else { Right("negative") })
assert_true(result is Left(10))

let right : Either[Int, String] = Right("hello")
let result = right.left_and_then(x => Left(x * 2))
assert_true(result is Right("hello"))

#
Either::left_or

fn[L, R] Either::left_or(self : Either[L, R], default : L) -> L

Returns the Left value if present, otherwise returns the provided default.

let left_value: Either[Int, String] = Left(42)
assert_eq(left_value.left_or(0), 42)

let right_value: Either[Int, String] = Right("hello")
assert_eq(right_value.left_or(0), 0)

#
Either::left_or_else

fn[L, R] Either::left_or_else(self : Either[L, R], f : () -> L raise?) -> L raise?

Returns the Left value if present, otherwise returns the result of calling the provided function.

let left_value: Either[Int, String] = Left(42)
assert_eq(left_value.left_or_else(() => 0), 42)

let right_value: Either[Int, String] = Right("hello")
assert_eq(right_value.left_or_else(() => 100), 100)

#
Either::left_unwrap

#alias(unwrap_left)
fn[L, R] Either::left_unwrap(self : Either[L, R]) -> L

Unwraps the Left value from an Either. Aborts if the Either is a Right variant.

let left_value: Either[Int, String] = Left(42)
let unwrapped = left_value.left_unwrap()
assert_eq(unwrapped, 42)

#
Either::map

fn[T] Either::map(self : Either[T, T], f : (T) -> T raise?) -> Either[T, T] raise?

Apply the function f to the value in either the Left or Right variant when both variants have the same type.

let left : Either[Int, Int] = Left(5)
let new_left = left.map(x => x * 2)
assert_true(new_left is Left(10))

let right : Either[Int, Int] = Right(5)
let new_right = right.map(x => x * 2)
assert_true(new_right is Right(10))

#
Either::map_either

#alias(bimap)
fn[L, ML, R, MR] Either::map_either(self : Either[L, R], fl : (L) -> ML raise?, fr : (R) -> MR raise?) -> Either[ML, MR] raise?

Apply the functions f and g to the Left and Right variants respectively.

This is equivalent to bimap in Haskell.

let left : Either[Int, String] = Left(123)
let new_left = left.map_either(x => x + 1, s => s + " world")
assert_true(new_left is Left(124))

let right : Either[Int, String] = Right("hello")
let new_right = right.map_either(x => x + 1, s => s + " world")
assert_true(new_right is Right("hello world"))

#
Either::map_left

fn[L, R, U] Either::map_left(self : Either[L, R], f : (L) -> U raise?) -> Either[U, R] raise?

Apply the function f on the value in the Left variant, if it is present rewrapping the result in Left.

let left : Either[Int, Unit] = Left(123)
let new_left = left.map_left(x => x + 1)
assert_true(new_left is Left(124))

let right : Either[Int, String] = Right("hello")
let new_right = right.map_left(x => x + 1)
assert_true(new_right is Right("hello"))

#
Either::map_right

fn[L, R, U] Either::map_right(self : Either[L, R], f : (R) -> U raise?) -> Either[L, U] raise?

Apply the function f on the value in the Right variant, if it is present rewrapping the result in Right.

let left : Either[Int, String] = Left(123)
let new_left = left.map_right(x => x + " world")
assert_true(new_left is Left(123))

let right : Either[Unit, String] = Right("hello")
let new_right = right.map_right(x => x + " world")
assert_true(new_right is Right("hello world"))

#
Either::right

fn[L, R] Either::right(self : Either[L, R]) -> R?

Convert the right side of Either[L, R] to an Option[R].

let values : Array[Either[Int, String]] = [Left(1), Right("two"), Left(3)]
assert_true(values[0].right() is None)
assert_true(values[1].right() is Some(_))
assert_true(values[2].right() is None)

#
Either::right_and_then

fn[L, R, S] Either::right_and_then(self : Either[L, R], f : (R) -> Either[L, S] raise?) -> Either[L, S] raise?

Applies a function to the Right value if present, returning the result. If the Either is Left, returns the Left value unchanged. This is a monadic bind operation for the Right side.

let right : Either[String, Int] = Right(5)
let result = right.right_and_then(x => if x > 0 { Right(x * 2) } else { Left("negative") })
assert_true(result is Right(10))

let left : Either[String, Int] = Left("error")
let result2 = left.right_and_then(x => Right(x * 2))
assert_true(result2 is Left("error"))

#
Either::right_or

fn[L, R] Either::right_or(self : Either[L, R], default : R) -> R

Returns the Right value if present, otherwise returns the provided default.

let right_value: Either[Int, String] = Right("hello")
assert_eq(right_value.right_or("default"), "hello")

let left_value: Either[Int, String] = Left(42)
assert_eq(left_value.right_or("default"), "default")

#
Either::right_or_else

fn[L, R] Either::right_or_else(self : Either[L, R], f : () -> R raise?) -> R raise?

Returns the Right value if present, otherwise returns the result of calling the provided function.

let right_value: Either[Int, String] = Right("hello")
assert_eq(right_value.right_or_else(() => "default"), "hello")

let left_value: Either[Int, String] = Left(42)
assert_eq(left_value.right_or_else(() => "computed"), "computed")

#
Either::right_unwrap

#alias(unwrap_right)
fn[L, R] Either::right_unwrap(self : Either[L, R]) -> R

Unwraps the Right value from an Either. Aborts if the Either is a Left variant.

let right_value: Either[Int, String] = Right("hello")
let unwrapped = right_value.right_unwrap()
assert_eq(unwrapped, "hello")

#
Either::to_result

fn[L, R] Either::to_result(self : Either[L, R]) -> Result[R, L]

Converts an Either[L, R] to Result[R, L]. Right values become Ok, Left values become Err.

let right_value: Either[String, Int] = Right(42)
let result_ok = right_value.to_result()
assert_true(result_ok is Ok(42))

let left_value: Either[String, Int] = Left("error")
let result_err = left_value.to_result()
assert_true(result_err is Err("error"))

#
collect_lefts

#alias(lefts_collect)
fn[L, R] collect_lefts(eithers : Array[Either[L, R]]) -> Array[L]

Collects all Left values from an array of Either values into a new array. Right values are ignored.

let eithers : Array[Either[Int, String]] = [Left(1), Right("a"), Left(2), Right("b"), Left(3)]
let lefts = collect_lefts(eithers)
assert_eq(lefts, [1, 2, 3])

let all_rights : Array[Either[Int, String]] = [Right("a"), Right("b")]
let no_lefts = collect_lefts(all_rights)
assert_eq(no_lefts, [])

#
collect_rights

#alias(rights_collect)
fn[L, R] collect_rights(eithers : Array[Either[L, R]]) -> Array[R]

Collects all Right values from an array of Either values into a new array. Left values are ignored.

let eithers : Array[Either[Int, String]] = [Left(1), Right("a"), Left(2), Right("b"), Left(3)]
let rights = collect_rights(eithers)
assert_eq(rights, ["a", "b"])

let all_lefts : Array[Either[Int, String]] = [Left(1), Left(2)]
let no_rights = collect_rights(all_lefts)
assert_eq(no_rights, [])

#
from_option_left

fn[L, R] from_option_left(v : L?) -> Either[L, R]

Converts an Option[L] to Either[L, R], placing the value in the Left variant. Aborts if the option is None.

let some_value: Int? = Some(42)
let result : Either[Int, Unit] = from_option_left(some_value)
assert_true(result is Left(42))

#
from_option_left_or

fn[L, R] from_option_left_or(v : L?, default : R) -> Either[L, R]

Converts an Option[L] to Either[L, R], placing the value in the Left variant. If the option is None, returns Right with the provided default value.

let some_value: Int? = Some(42)
let result = from_option_left_or(some_value, "default")
assert_true(result is Left(42))

let none_value: Int? = None
let result2 = from_option_left_or(none_value, "default")
assert_true(result2 is Right("default"))

#
from_option_left_or_else

fn[L, R] from_option_left_or_else(v : L?, f : () -> R raise?) -> Either[L, R] raise?

Converts an Option[L] to Either[L, R], placing the value in the Left variant. If the option is None, returns Right with the result of calling the provided function.

let some_value: Int? = Some(42)
let result = from_option_left_or_else(some_value, () => "computed")
assert_true(result is Left(42))

let none_value: Int? = None
let result2 = from_option_left_or_else(none_value, () => "computed")
assert_true(result2 is Right("computed"))

#
from_option_right

fn[L, R] from_option_right(v : R?) -> Either[L, R]

Converts an Option[R] to Either[L, R], placing the value in the Right variant. Aborts if the option is None.

let some_value: String? = Some("hello")
let result : Either[Unit, String] = from_option_right(some_value)
assert_true(result is Right("hello"))

#
from_option_right_or

fn[L, R] from_option_right_or(v : R?, default : L) -> Either[L, R]

Converts an Option[R] to Either[L, R], placing the value in the Right variant. If the option is None, returns Left with the provided default value.

let some_value: String? = Some("hello")
let result = from_option_right_or(some_value, 42)
assert_true(result is Right("hello"))

let none_value: String? = None
let result2 = from_option_right_or(none_value, 42)
assert_true(result2 is Left(42))

#
from_option_right_or_else

fn[L, R] from_option_right_or_else(v : R?, f : () -> L raise?) -> Either[L, R] raise?

Converts an Option[R] to Either[L, R], placing the value in the Right variant. If the option is None, returns Left with the result of calling the provided function.

let some_value: String? = Some("hello")
let result = from_option_right_or_else(some_value, () => 42)
assert_true(result is Right("hello"))

let none_value: String? = None
let result2 = from_option_right_or_else(none_value, () => 42)
assert_true(result2 is Left(42))

#
from_result

fn[L, R] from_result(r : Result[R, L]) -> Either[L, R]

Converts a Result[R, L] to Either[L, R]. Success values become Right, error values become Left.

let ok_result: Result[String, Int] = Ok("success")
let either_ok = from_result(ok_result)
assert_true(either_ok is Right("success"))

let err_result: Result[String, Int] = Err(404)
let either_err = from_result(err_result)
assert_true(either_err is Left(404))

#
left

fn[L, R] left(l : L) -> Either[L, R]

Creates a new Left variant of Either.

let left: Either[Int, String] = left(123)
assert_true(left is Left(123))

#
partition

fn[L, R] partition(eithers : Array[Either[L, R]]) -> (Array[L], Array[R])

Partitions an array of Either values into separate arrays of Left and Right values. Returns a tuple containing an array of all Left values and an array of all Right values.

let eithers : Array[Either[Int, String]] = [Left(1), Right("a"), Left(2), Right("b"), Left(3)]
let (lefts, rights) = partition(eithers)
assert_eq(lefts, [1, 2, 3])
assert_eq(rights, ["a", "b"])
fn[L, R] right(r : R) -> Either[L, R]

Creates a new Right variant of Either.

let right: Either[Int, String] = right("hello")
assert_true(right is Right("hello"))

Source Files