1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use std::marker::PhantomData;

use crate::internal::functional::{
  nat::*,
  row::*,
};

pub struct Either<A, B>
{
  phantom: PhantomData<(A, B)>,
}

impl<A, B> ToRow for Either<A, B>
{
  type Row = (A, (B, ()));
}

pub type EitherRow<A, B> = Sum<A, Sum<B, Bottom>>;

#[allow(non_upper_case_globals)]
pub const LeftLabel: ChoiceSelector<Z> = <ChoiceSelector<Z>>::new();

#[allow(non_upper_case_globals)]
pub const RightLabel: ChoiceSelector<S<Z>> = <ChoiceSelector<S<Z>>>::new();

pub enum EitherChoice<A, B>
{
  Left(A),
  Right(B),
}

pub use EitherChoice::{
  Left,
  Right,
};

impl<A, B> From<Sum<A, Sum<B, Bottom>>> for EitherChoice<A, B>
{
  fn from(row: Sum<A, Sum<B, Bottom>>) -> EitherChoice<A, B>
  {
    match row {
      Sum::Inl(a) => Left(a),
      Sum::Inr(Sum::Inl(b)) => Right(b),
      Sum::Inr(Sum::Inr(bot)) => match bot {},
    }
  }
}