generics
Generics: type parameters, Option and Result, and the list builtins.
examples/data/generics.dawn
# Generics: type parameters, Option and Result, and the list builtins.
#
# Run: dawn run examples/data/generics.dawn
type Tree[T] =
| Leaf
| Node(left: Tree[T], value: T, right: Tree[T])
fn insert(t: Tree[Int], v: Int) -> Tree[Int] =
match t {
Leaf -> Node(Leaf, v, Leaf)
Node(l, x, r) ->
if v < x { Node(insert(l, v), x, r) }
else { Node(l, x, insert(r, v)) }
}
fn total(t: Tree[Int]) -> Int =
match t {
Leaf -> 0
Node(l, v, r) -> total(l) + v + total(r)
}
fn or_default[T](o: Option[T], d: T) -> T =
match o {
Some(v) -> v
None -> d
}
fn safe_div(a: Int, b: Int) -> Result[Int, String] =
if b == 0 { Err("division by zero") } else { Ok(a / b) }
pub fn main() -> Unit !io = {
# generic tree
let e: Tree[Int] = Leaf
let t = insert(insert(insert(e, 5), 2), 8)
println("tree total: ${total(t)}")
# Option + inference across arguments
println("or_default(None, 7) = ${or_default(None, 7)}")
println(or_default(Some("hello"), "fallback"))
# Result
match safe_div(10, 0) {
Ok(v) -> println("ok $v")
Err(m) -> println("err: $m")
}
# lists
let xs = range(1, 5) ++ [10, 20]
println("len = ${len(xs)}")
println("get(xs, 4) = ${or_default(get(xs, 4), -1)}")
println("lists equal: ${[1, 2] ++ [3] == [1, 2, 3]}")
}
test "the tree keeps everything that went in" {
let e: Tree[Int] = Leaf
let t = insert(insert(insert(e, 5), 2), 8)
assert total(t) == 15
}
test "one generic function serves every element type" {
assert or_default(None, 7) == 7
assert or_default(Some("hello"), "fallback") == "hello"
}
test "a failure is a value" {
assert safe_div(10, 2) == Ok(5)
assert safe_div(10, 0) == Err("division by zero")
}