tur/either
binary sum type Either[L R]: Left l or Right r.
A true tagged-union sum: a value is either (Left l) carrying an L, or (Right r) carrying an R, with the two payloads living in distinct union arms (no shadowing). This is the canonical "one of two differently-typed things" type -- isomorphic to Result[R L] but with neutral naming, and the building block for ArrowChoice and session-typed protocol choices.
By convention Right is the "success"/"main" arm and Left the "error"/"other" arm, so the Functor instance maps over Right and leaves Left untouched (right-biased), matching Haskell's Either.
Runtime / FFI layout (single shared, type-erased struct):
typedef struct tur_adt_Either {
int tag; // 0 = Left, 1 = Right
union {
struct { int64_t _0; } Left;
struct { int64_t _0; } Right;
} as;
} tur_adt_Either;
Construct with ctor_Left(v) / ctor_Right(v); both heap-allocate and return an int64_t handle. The emitted C symbol is ADT-qualified -- ctor_Either_Left / ctor_Either_Right -- so two ADTs sharing a constructor name do not collide; the bare spelling above stays available as a macro alias because no other ADT in the program defines Left or Right. Give an ADT of your own a constructor named Left and the bare alias is gone (a cc error naming it), because there is then no unambiguous meaning for it -- use the qualified symbol. See docs/archive/duplicate-ctor-names-collide-in-emitted-c.md.
Payloads are erased to int64_t at the C boundary, the same way Option[A] / Result[A B] erase theirs.
Since: Phase sum-types-either
Either
(defdata Either :copy [L R] (Left L) (Right R))
left?
(left? [L R])
is this Either a Left?
| e | an Either[L R] handle |
true when e is (Left _), false when (Right _).
(left? (Left 3)) ; => true (left? (Right 3)) ; => false
Since: Phase sum-types-either
right?
(right? [L R])
is this Either a Right?
| e | an Either[L R] handle |
true when e is (Right _), false when (Left _).
(right? (Right 3)) ; => true (right? (Left 3)) ; => false
Since: Phase sum-types-either
from-left
(from-left [L R])
extract the Left payload, or a default when e is a Right.
| dflt | value returned when e is a Right | |
| e | an Either[L R] handle |
The L payload when e is (Left l), else dflt.
(from-left 0 (Left 7)) ; => 7 (from-left 0 (Right 7)) ; => 0
Since: Phase sum-types-either
from-right
(from-right [L R])
extract the Right payload, or a default when e is a Left.
| dflt | value returned when e is a Left | |
| e | an Either[L R] handle |
The R payload when e is (Right r), else dflt.
(from-right 0 (Right 7)) ; => 7 (from-right 0 (Left 7)) ; => 0
Since: Phase sum-types-either
either
(either [L R C])
eliminate an Either by applying one of two functions.
The fundamental Either destructor (its catamorphism): runs on-left over the L payload of a Left, or on-right over the R payload of a Right. Both branches must produce the same result type.
| on-left | function applied to the Left payload (carried as a fat closure) | |
| on-right | function applied to the Right payload (carried as a fat closure) | |
| e | an Either[L R] handle |
(on-left l) when e is (Left l), else (on-right r).
(either negate id (Left 5)) ; => -5 (either negate id (Right 5)) ; => 5
Since: Phase sum-types-either
either-map
(either-map [L A B])
map a function over the Right arm (right-biased).
Applies f to the payload of a Right, rebuilding a Right; passes a Left through unchanged. This is the Functor map for Either fixed in its Left type parameter.
| f | function applied to the Right payload (carried as a fat closure) | |
| e | an Either[L R] handle |
(Right (f r)) when e is (Right r), else e unchanged.
(either-map inc (Right 4)) ; => (Right 5) (either-map inc (Left 4)) ; => (Left 4)
Since: Phase sum-types-either
either-map-left
(either-map-left [A B R])
map a function over the Left arm.
Applies f to the payload of a Left, rebuilding a Left; passes a Right through unchanged. The mirror of either-map.
| f | function applied to the Left payload (carried as a fat closure) | |
| e | an Either[L R] handle |
(Left (f l)) when e is (Left l), else e unchanged.
(either-map-left inc (Left 4)) ; => (Left 5) (either-map-left inc (Right 4)) ; => (Right 4)
Since: Phase sum-types-either
Functor[(Either E)]
(definstance Functor [(Either E)])
right-biased Functor for Either: map over Right.
Since: Phase sum-types-either