1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct Position(usize);
12
13impl Position {
14 #[must_use]
16 pub fn value(&self) -> usize {
17 self.0
18 }
19}
20
21impl From<usize> for Position {
22 fn from(value: usize) -> Self {
23 Self(value)
24 }
25}
26
27impl std::fmt::Display for Position {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 write!(f, "{}", self.0)
30 }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
35pub struct VarName(String);
36
37impl VarName {
38 #[must_use]
40 pub fn as_str(&self) -> &str {
41 &self.0
42 }
43}
44
45impl From<String> for VarName {
46 fn from(value: String) -> Self {
47 Self(value)
48 }
49}
50
51impl From<&str> for VarName {
52 fn from(value: &str) -> Self {
53 Self(value.to_owned())
54 }
55}
56
57impl std::fmt::Display for VarName {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 f.write_str(&self.0)
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
69pub enum Expr {
70 Var(VarName),
72 Lam {
74 param: VarName,
76 body: Box<Expr>,
78 },
79 App {
81 func: Box<Expr>,
83 arg: Box<Expr>,
85 },
86 Let {
88 name: VarName,
90 value: Box<Expr>,
92 body: Box<Expr>,
94 },
95 Fix {
98 name: VarName,
100 body: Box<Expr>,
102 },
103}
104
105impl Expr {
106 #[must_use]
108 pub fn var(name: impl Into<VarName>) -> Self {
109 Self::Var(name.into())
110 }
111
112 #[must_use]
114 pub fn lam(param: impl Into<VarName>, body: Self) -> Self {
115 Self::Lam {
116 param: param.into(),
117 body: Box::new(body),
118 }
119 }
120
121 #[must_use]
123 pub fn app(func: Self, arg: Self) -> Self {
124 Self::App {
125 func: Box::new(func),
126 arg: Box::new(arg),
127 }
128 }
129
130 #[must_use]
132 pub fn bind(name: impl Into<VarName>, value: Self, body: Self) -> Self {
133 Self::Let {
134 name: name.into(),
135 value: Box::new(value),
136 body: Box::new(body),
137 }
138 }
139
140 #[must_use]
142 pub fn fix(name: impl Into<VarName>, body: Self) -> Self {
143 Self::Fix {
144 name: name.into(),
145 body: Box::new(body),
146 }
147 }
148}
149
150impl std::fmt::Display for Expr {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 match self {
153 Self::Var(name) => write!(f, "{name}"),
154 Self::Lam { param, body } => write!(f, "(\\{param}. {body})"),
155 Self::App { func, arg } => write!(f, "({func} {arg})"),
156 Self::Let { name, value, body } => {
157 write!(f, "(let {name} = {value} in {body})")
158 }
159 Self::Fix { name, body } => write!(f, "(fix {name}. {body})"),
160 }
161 }
162}