-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16_full_mixins.sc
77 lines (53 loc) · 1.57 KB
/
16_full_mixins.sc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// mixins - from Martin Odersky - The Simple Parts - San Fransisco Scala Users Group 2014
println("Welcome to the Scala Full Mixins") //> Welcome to the Scala Full Mixins
trait Graphs {
type Node
type Edge
type Graph <: GraphSig
def pred(e: Edge): Node
def succ(e: Edge): Node
def newGraph(nodes: Set[Node], edges: Set[Edge]): Graph
trait GraphSig {
def nodes: Set[Node]
def edges: Set[Edge]
def outgoing(n: Node): Set[Edge]
def incoming(n: Node): Set[Edge]
def sources: Set[Node]
}
}
trait AbstractModel extends Graphs {
class Graph(val nodes: Set[Node], val edges: Set[Edge]) extends GraphSig {
def outgoing(n: Node) = edges filter { succ(_) == n }
def incoming(n: Node) = edges.filter(pred(_) == n)
lazy val sources = nodes filter (incoming(_).isEmpty)
}
def newGraph(nodes: Set[Node], edges: Set[Edge]) = new Graph(nodes, edges)
}
case class Person(name: String, age: Int)
trait ConcreteModel extends Graphs {
type Node = Person
type Edge = (Person, Person)
def succ(e: Edge) = e._1
def pred(e: Edge) = e._2
}
//
// Emily -> Katelyn -> Joshua
// ////////////////////////////////////
class MyKidsGraph extends AbstractModel with ConcreteModel
val e = Person("emily", 19)
val k = Person("katelyn", 17)
val j = Person("joshua", 14)
val g = new MyKidsGraph().newGraph(Set(e, k, j), Set((e, k), (k, j)))
g.nodes
g.edges
g.sources
g.outgoing(e)
g.outgoing(k)
g.outgoing(j)
g.incoming(e)
g.incoming(k)
g.incoming(j)
//
//
//
//