-
Notifications
You must be signed in to change notification settings - Fork 0
Draft: Generics & Contracts
Felix Schoeller edited this page Jun 17, 2020
·
2 revisions
// the file “…” notation just means, that this is in file map.kan
file “map.kan” {
// A contract contains a list of statements, which must be valid for the given // type parameters (here just T) // In this case, it just means that a variable of type *T must have a method named hash, which // returns and i32 type Hash[T] contract { let t: *T = undefined let h: i32 = t.hash() } // Entry takes 2 type parameters. K is bound by the Hash contract, since we need // to hash the Key. // V is unbound. It could be any type type Entry[K: Hash, V] struct { key: K, value: V } // The HashMap basically inherited the bounds of Entry, since it needs those for the entries // array type HashMap[K: Hash, V] struct { len: i32, // An array containing an unknown amount of Entry[K, V] struct instances entries: []Entry[K, V] } // the insert function needs K and V, which are implicitly bound by Map[K, V] def [K, V] (m: *Map[K, V]) insert() { let entries: []Entry[K, V] = m.entries; // ... }
}
file “person.kan” {
type Person struct { name: string } def (p: *Person) hash(): i32 { let hash = 0; for let i = 0; i < p.name.len; i += 1 { hash += p.name[i]; } return hash; }
}
file “main.kan” {
import "map" as m import "person" as p import "math" type Number[n: T] contract { n = n + n n = n * n n = n / n n = n - n } type Vector[v: V, Scalar: Number] contract { let s: Scalar = undefined v = v.add(&v) v = v.scale(s) s = v.len() } type Vec2 struct { x: f32, y: f32 } def (self: Vec2) add(other: Vec2): Vec2 { return Vec2 { x: self.x + other.x, y: self.y + other.y } } def (self: Vec2) scale(scalar: f32): Vec2 { return Vec2 { x: self.x * scalar, y: self.y * scalar } } def (self: Vec2) len(): f32 { return math.sqrt(self.x * self.x + self.y * self.y) } type MyPerson new = p.Person def (p: *MyPerson) hash(): i32 { return 0 } def main() { let felix = p.Person { name: "felix" } felix.hash() let map1: m.Map[p.Person, string] = ... let map2: m.Map[MyPerson, string] = ... map.insert(felix, "123") }
}
file “print.kan” {
type Print[t: T] contract { t.print() } type Display[T] contract { let t: T = undefined let s: string = t.to_string() } def [T: Print] print(s: []T) { for let i = 0; i < s.len; i += 1 { s[i].print(); } } def [T: Display] to_string(s: []T): []string { let ret: []string = new [string, s.len]; for let i = 0; i < s.len; i += 1 { ret[i] = s[i].to_string() } return ret }
}