LICHEN

(barely working edition)

Try

Syntax

Functions and let bindings

let double (x : Int) = x + x

let main =
    let x = double 5
    in x + 1

Sum types

type Option a = | None | Some a
type List a   = | Nil  | Cons a (List a)

Records

type Hero = { class : Class, hp : Int, inv : Inventory }

let hero : Hero = { class = Rogue, hp = 100, inv = Empty }
let healed = { hero with hp = 75 }

Pattern matching

let describe (m : Monster) : String =
    match m with
    | Goblin -> "a goblin"
    | Dragon -> "a dragon"

let fst (p : (Int, Int)) : Int =
    match p with
    | (a, _) -> a

Refinement types — checked at compile-time

type Nat = Int{>= 0}

let abs : Int -> Nat
let abs x =
    match x >= 0 with
    | True  -> x
    | False -> 0 - x

let clamp : Int -> Int{>= lo} -> Int -> Int{r | r >= lo && r <= hi}
let clamp lo hi x =
    match x < lo with
    | True  -> lo
    | False -> (match x > hi with
               | True  -> hi
               | False -> x)

Traits and instances

trait Power t = { power : t -> Int }

given Power Monster = {
    power (m : Monster) : Int =
        match m with
        | Goblin -> 5
        | Dragon -> 30
}

Polymorphism

let id : forall a. a -> a
let id x = x

let combinedPower : forall a. a -> a -> Int where Power a
let combinedPower x y = Power.power x + Power.power y

Lambdas and closures

let makeScaler (c : Class) : Int -> Int =
    match c with
    | Warrior -> \base -> base + base / 4
    | Rogue   -> \base -> base + base / 2

let applyTwice : forall a. (a -> a) -> a -> a
let applyTwice f x = f (f x)

Algebraic effects

effect Stdout = { print : Int -> Int }

let main : Int [Stdout] =
    handle
        let x = do Stdout.print 42 in
        x
    with
    | Stdout.print s -> resume s

Proofs

-- prove: lichen must verify the proposition
let colony = season rock Rock in
prove census colony == 2 in ...

-- assume: trust without proof (escape hatch)
assume doubleScaled >= 10 in ...

Operators — defined via traits that you can implement

infixl 6 +          infixl 7 *
infix  4 ==         infixr 3 &&
infixr 5 ++         infixr 2 ||

Writing rules

Lichen grows in many ways. Write your patches in your own way; lichen programs mean the same with all words and symbols on one line as with each on a separate line.