ivo/examples/examples.ivo

197 lines
4.4 KiB
Plaintext
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env -S ivo -c
// syntax for algebraic data types
type
+ 0
+ 1+
type List a
+ []
+ _∷_ a (List a)
// syntax for algebraic codata types
type Stream a
& Head a
& Tail (Stream a)
// syntax for generalized algebraic (co)data types
type Vec a : → Type
[] : Vec a 0
_∷_ : ∀ n → a → Vec a n → Vec a (1+ n)
// syntax for mutually-recursive types
types
Even Odd : → Type
0even : Even 0
1+odd : ∀ n → Odd n → Even (1+ n)
1+even : ∀ n → Even n → Odd (1+ n)
// syntax for higher-inductive type
type Multiset a
empty : Multiset a
singleton : a → Multiset a
append : Multiset a → Multiset a → Multiset a
append_commutative : (x y : Multiset a) → append x y ≡ append y x
// syntax for inductive-recursive types? (needs work)
types a _#_
DList : Type
Fresh : a → Dlist a → Type
[] : DList a
_∷_#_ : (head : a) → (tail : DList a) → Fresh head tail → DList a
fresh[] : (x : a) → Fresh x []
fresh∷ : (x : a) → (head : a) → (tail : DList a) → (p : Fresh head tail) → x # head → Fresh x tail → Fresh x (head ∷ tail # p)
// syntax for traits
trait Functor f
map : ∀ a b → (a → b) → f a → f b
// short for `open data type List a`
// short for `open implicit trait Functor f`
// generated signatures
sig
: Type
_Sig : Sig
_Impl : _Sig
0 :
1+ :
pattern 0 1+
complete 0 1+
_rec : ∀ a ⇒ a → ( a → a ) → → a
_ind : (C : → Type) ⇒ C 0 → (∀ n → C n → C (1+ n)) → (n : ) → C n
recurse : Sig → ...
induct : Sig → ...
baseFunctor : Sig → Sig
sig
Functor : Type → Sig
map : ∀ f ⇒ Functor f ⇒ ∀ a b ⇒ (a → b) → f a → f b
inductive type
type List a
+ []
+ _:+_ a (List a)
type Stream a
& Head a
& Tail (Stream a)
type Vec a : → Type
[] : Vec a 0
_:+_ : ∀ n → a → Vec a n → Vec a (1+ n)
sig
: Type
Z :
S :
sig
List : Type → Type
[] : ∀ a → List a
_:+_ : ∀ a → a → List a → List a
sig
Stream : Type → Type
Head : ∀ a → Stream a → a
Tail : ∀ a → Stream a → Stream a
iterate : ∀ a → (a → a) → a → → a
iterate f x
0 → []
1+ n → x :+ iterate f (f x) n
iterate = \ f x n → case n {
0 → [];
1+ n → x :+ iterate f (f x) n;
};
iterate f x = \case
0 -> []
1+ n -> x : iterate f (f x) n
append : ∀ a → List a → List a → List a
append xs ys = case xs
[] → ys
x :+ xs → x :+ append xs ys
reverse : ∀ a → List a → List a
reverse
[] → []
x :+ xs → append (reverse xs) [ x ]
church : Type
church = ∀ a → (a → a) → a → a
churchS : church → church
churchS n f x = f (n f x)
church+ : church → church → church
church+ n = n churchS
// Create a list by iterating `f` `n` times:
iterate = λ f x {
Z → [];
1+ n → x :+ iterate f (f x) n;
};
// Use the iterate function to count to 10:
countToTen : [Nat] =
let countTo = iterate +1 1
in countTo 10;
// Append two lists together:
append = λ xs ys → case xs {
[] → ys;
x :+ xs → x :+ append xs ys;
};
// Reverse a list:
reverse = λ {
[] → [];
_:+_ x xs → append (reverse xs) [ x ]
};
// Basic operations on church-encoded naturals.
churchS = λ n f x → f (n f x);
church+ = λ n → n churchS;
main =
// Now we can reverse `"reverse"`:
let reverseReverse : [Char] = reverse "reverse";
// Calculating `3 + 2` with the help of Church-encoded numerals:
let threePlusTwo : Nat =
let Sf = \n f x. f (n f x)
; plus = \x. x Sf
in plus (\f x. f (f (f x))) (\f x. f (f x)) S Z;
letrec undefined = undefined;
// This expression would loop forever, but `callcc` saves the day!
let callccSaves : Nat = S (callcc \k. undefined (k Z));
// And if it wasn't clear, this is what the `Char` constructor does:
let charB : Char = { Char c -> Char (S c) } 'a;
// (it outputs `'b`)
// pack all of the examples into tuples so the main function can print them
let main =
( countToTen
, ( reverseReverse
, ( callccSaves
, charB
)))