1use typenum::{B0, B1};
2
3pub struct True;
4pub struct False;
5
6pub trait TruthValue {}
7impl TruthValue for True {}
8impl TruthValue for False {}
9
10pub trait Or {
11 type Out;
12}
13impl Or for (True, True) {
14 type Out = True;
15}
16impl Or for (True, False) {
17 type Out = True;
18}
19impl Or for (False, True) {
20 type Out = True;
21}
22impl Or for (False, False) {
23 type Out = False;
24}
25
26pub trait And {
27 type Out;
28}
29impl And for (True, True) {
30 type Out = True;
31}
32impl And for (True, False) {
33 type Out = False;
34}
35impl And for (False, True) {
36 type Out = False;
37}
38impl And for (False, False) {
39 type Out = False;
40}
41
42pub trait Not {
43 type Out;
44}
45impl Not for True {
46 type Out = False;
47}
48impl Not for False {
49 type Out = True;
50}
51
52pub trait Bool {
53 type Out;
54}
55impl Bool for B1 {
56 type Out = True;
57}
58impl Bool for B0 {
59 type Out = False;
60}
61
62pub trait Truthy {}
63impl Truthy for True {}
64
65pub trait Falsy {}
66impl Falsy for False {}
67
68pub mod monoid {
69 use super::*;
70 use crate::traits::{monoid::Mempty, semigroup::Semigroup};
71
72 pub struct Either;
73 pub struct Both;
74
75 impl<Lhs, Rhs> Semigroup<Lhs, Rhs> for Either
76 where
77 (Lhs, Rhs): Or,
78 {
79 type Mappend = <(Lhs, Rhs) as Or>::Out;
80 }
81 impl Mempty for Either {
82 type Out = False;
83 }
84
85 impl<Lhs, Rhs> Semigroup<Lhs, Rhs> for Both
86 where
87 (Lhs, Rhs): And,
88 {
89 type Mappend = <(Lhs, Rhs) as And>::Out;
90 }
91 impl Mempty for Both {
92 type Out = True;
93 }
94}