Something went wrong. Try again.
The Monad language. Dependent types, functional programming compiled with LLVM. Hobby project. monad-lang.org
dependent-types language compiler programming-language functional-programming
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273/// Derive Macros Example — BEq, BOrd, Debug, and Lens via `#[derive ...]`////// Demonstrates deriving structural equality, ordering, a rust-style debug/// representation, and per-field lenses for a struct and a plain/// multi-constructor `type`, all with a single `#[derive ...]` attribute/// per declaration. Each derive is a `.mo`-authored macro in/// `std/derive.mo`, built on a handful of reflection intrinsics in the/// compiler itself — see that file's doc comments for the full design.#![mote { name := "derive", deps := [init, std] }]// `derive_beq`/`derive_bord`/`derive_debug`/`derive_lens` are only ever// invoked via the `#[derive BEq BOrd Debug Lens]` attribute below (macro// dispatch by name string, not an ordinary term reference), so the// checker's "unused import" analysis flags this line as a false// positive — confirmed by removing it: `#[derive BEq]` then fails with// "macro `derive_beq` not found". Keep this import despite the warning.use std::derive {derive_beq, derive_bord, derive_debug, derive_lens}use init::optics {Lens, set, view}use std::debug {Debug}#[derive BEq BOrd Debug Lens]struct Point { x : I64, y : I64,}#[test]def test_point_equality : Bool := let p1 : Point := { x := 1, y := 2 } in let p2 : Point := { x := 1, y := 2 } in let p3 : Point := { x := 1, y := 3 } in p1 == p2 && Bool.not (p1 == p3)#[test]def test_point_ordering : Bool := let p1 : Point := { x := 1, y := 2 } in let p2 : Point := { x := 1, y := 3 } in p1 < p2 && p2 > p1#[test]def test_point_debug : Bool := let p : Point := { x := 1, y := 2 } in Debug.debug p == "Point { x: 1, y: 2 }"#[test]def test_point_lens : Bool := let p : Point := { x := 1, y := 2 } in view Point.x p == 1 && view Point.y (set Point.y 9 p) == 9/// Derives work on multi-constructor `type`s too — `BEq`/`BOrd`/`Debug`/// cover every constructor; `Lens` is deliberately not requested here,/// since a lens focuses on exactly one field of exactly one shape and/// wouldn't apply to a sum type (see `init.optics`'s `Prism` instead).#[derive BEq BOrd Debug]type Suit { hearts, spades, number (rank : I64),}#[test]def test_suit_equality : Bool := Suit.number 7 == Suit.number 7 && Bool.not (Suit.hearts == Suit.spades)#[test]def test_suit_ordering_follows_declaration_order : Bool := Suit.hearts < Suit.spades && Suit.spades < Suit.number 0#[test]def test_suit_debug : Bool := Debug.debug Suit.hearts == "Suit::hearts" && Debug.debug (Suit.number 7) == "Suit::number { rank: 7 }"