-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtraits.gleam
114 lines (90 loc) · 2.29 KB
/
traits.gleam
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import gleam/string
// Define
pub trait Named {
fn name(self) -> String
}
// compiled to
// -record(namedTrait, {name=undefined}).
// namedTrait_name(Trait) -> element(2, Trait).
// Use the trait, taking any arguments that implement the trait
fn whats_the_name(n: Named) -> String {
string.append("the name is: ", name(n))
}
// compiles to
// whats_the_name(N, N_Named) ->
// gleam@string:append(<<"the name is: ">>, (namedTrait_name(N_Named))(N)).
fn have_same_name(x: Named, y: Named) -> Bool {
name(x) == name(y)
}
// compiles to
// have_same_name(X, X_Named, Y, Y_Named) ->
// (namedTrait_name(X_Named))(X) =:= (namedTrait_name(Y_Named))(Y).
// Define some types that implement the trait
pub struct Cat {
name: String
}
let trait Cat: Named {
fn name(self) -> String {
let Cat(name) = self
name
}
}
// compiles to
// namedTrait_Cat() ->
// {namedTrait,
// fun namedTrait_Cat_name/1}.
// namedTrait_Cat_name(Self) ->
// {cat, Name} = Self,
// Name.
pub enum Person {
Friend(name: String)
Stranger
}
let trait Person: Named {
fn name(self) -> String {
case self {
Friend(name) -> name
Stranger -> "Unknown"
}
}
}
// Use the trait, taking arguments of concrete types that implement the trait
pub fn hello_kitty(cat: Cat) -> String {
string.append("Hello ", name(cat))
}
// There's no need to pass around a trait object here as it can be statically
// resolved. compiled to
// hello_kitty(Cat) ->
// gleam@string:append(<<"the name is: ">>, namedTrait_Cat_name(N)).
// We may want to be able have implementations that depend on the
// implementation of their parameter type
pub struct Wrapper(x) {
value: x
}
let trait Wrapper(x: Named): Named {
fn name(self) -> String {
let Wrapper(x) = self
name(x)
}
}
// compiles to
// namedTrait_Wrapper_name(X) ->
// {namedTrait,
// namedTrait_trait_Wrapper_name(X)}.
// namedTrait_Wrapper_name(X_Name) ->
// fun(Self) ->
// {wrapper, Name} = X,
// (namedTrait_name(X_Name))(Name).
// end.
// Deriving trait implementations
// The compiler can have built in support for a bunch of traits
pub enum Size {
Small
Medium
Large
}
derive trait Size: Show
derive trait Size: Eq
derive trait Size: Order
derive trait Size: FromAny
derive trait Size: ToAny