switch.fz
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature switch
#
# -----------------------------------------------------------------------
# switch is the parent feature of all choices
# that encode success and failure,
# e.g. option (something/nil)
# or outcome (something/error)
#
public switch(A type, B type /* NYI: B should be open generic */) :
choice A B,
# monad A (switch A B) NYI: does not work,
Sequence A
is
# NYI: CLEANUP: decide name: exists/ok, get/val?
# Does this switch contain a value of type A?
#
public exists => (switch.this ? A => true
| B => false)
# Does this switch contain a value of type A?
#
public ok => exists
# short-hand postfix operator for 'exists'
#
public postfix ?? => exists
# short-hand postfix operator for '!exists'
#
public postfix !! => !exists
# short-hand prefix operator for '!exists'
#
public prefix ! => !exists
# unwraps a switch that is known to contain a value
#
# this can only be called in cases where it is known for sure that this switch
# is not nil. A runtime error will be created otherwise.
#
public get
pre
safety: switch.this??
=>
switch.this ? a A => a
| B => fuzion.std.panic "switch.get called on B. Enable `safety` to obtain a precondition failure for debugging."
# unwrap value or get default
#
public get (default Lazy A) =>
switch.this ? a A => a
| B => default
# value of a switch that is known to contain a value
#
# This can only be called in cases where it is known for sure that this
# switch is not a B. A runtime error will be created otherwise.
#
public val A
pre
safety: switch.this??
=>
switch.this ? a A => a
| B => panic "switch.val called on B. Enable `safety` to obtain a precondition failure for debugging."
# value of a switch or default if switch contains B
#
public val(default A) A
=>
switch.this ? a A => a
| B => default
# synonym for infix >>=
#
# NYI: BUG: #4169 when replacing switch A B by switch.this
#
public and_then (f A -> switch A B) switch A B =>
match switch.this
a A => f a
b B => b
# returns o if outcome is ok, otherwise return the outcome's own
# error.
#
# NYI: BUG: #4169 when replacing switch A B by switch.this
#
public and (O type, o switch A B) switch A B =>
match switch.this
A => o
b B => b
# if this switch is nil return the result of f
# otherwise just return this switch.
#
# NYI: BUG: when replacing switch A B by switch.this
#
public or (f Lazy (switch A B)) switch A B =>
# NYI: BUG: #4169 require-condition2 failed: RefValue.java:74 "(!dfa._fuir.clazzIsRef(original._clazz), original._clazz == vc, dfa._fuir.clazzIsRef(rc));"
# if ok then switch.this else f()
match switch.this
a A => a
B => f()
# unwraps an switch if it exists, returns default value otherwise.
#
public or_else(default Lazy A) A =>
switch.this ? v A => v
| B => default
# converts switch into a list of either a single element in case
# switch.this.exists or `nil`otherwise
#
public redef as_list list A
=>
switch.this ? a A => a : nil
| B => nil
# convert this switch to an option
#
public as_option option A
=>
switch.this ? a A => a
| B => nil
# convert this switch to an outcome
#
public as_outcome outcome A
=>
switch.this ? a A => a
| B => error "switch.as_outcome: no error message provided"
# convert this switch to an outcome
#
public as_outcome(e error) outcome A
=>
switch.this ? a A => a
| B => e
# converts switch to a string
#
public redef as_string =>
match switch.this
a A => a.as_string
b B => b.as_string
last changed: 2025-01-23