calculator — expression evaluator with ADTs
A tiny tree-walking interpreter for arithmetic expressions. type Expr = | Num x | Add a b | Mul a b | Neg a defines the AST; eval recursively reduces it to an int.
\1 (examples/calculator.rail):
-- calculator.rail — expression evaluator using algebraic data types
--
-- Demonstrates: ADTs (type), pattern matching (match), recursive evaluation,
-- nested constructors
type Expr = | Num x | Add a b | Mul a b | Neg a
eval e = match e
| Num x -> x
| Add a b -> eval a + eval b
| Mul a b -> eval a * eval b
| Neg a -> 0 - eval a
describe e = match e
| Num x -> show x
| Add a b -> "add"
| Mul a b -> "mul"
| Neg a -> "neg"
main =
-- 5
let e1 = Num 5
let _ = print (show (eval e1))
-- 3 + 4 = 7
let e2 = Add (Num 3) (Num 4)
let _ = print (show (eval e2))
-- 6 * 7 = 42
let e3 = Mul (Num 6) (Num 7)
let _ = print (show (eval e3))
-- (2 * 3) + 4 = 10
let e4 = Add (Mul (Num 2) (Num 3)) (Num 4)
let _ = print (show (eval e4))
-- (3 + 4) * (5 + 6) = 77
let e5 = Mul (Add (Num 3) (Num 4)) (Add (Num 5) (Num 6))
let _ = print (show (eval e5))
-- neg(10) + 15 = 5
let e6 = Add (Neg (Num 10)) (Num 15)
let _ = print (show (eval e6))
0
\1
./rail_native run examples/calculator.rail
\1
5
7
42
10
77
5
This is the standard shape of every interpreter you'll write in Rail: an Expr ADT, an eval match that does one arm per constructor, and main building expression trees with the constructors directly.