1
- /** A possible type class encoding for
1
+ /** 1. Simple type classes with monomorphic implementations and direct extensions.
2
2
3
3
trait SemiGroup extends TypeClass {
4
4
def add(that: This): This
23
23
def unit = ""
24
24
}
25
25
26
+ enum Nat extends Monoid {
27
+ case Z
28
+ case S(n: Nat)
29
+
30
+ def add(that: Nat): Nat = this match {
31
+ case S => that
32
+ case S(n) => S(n.add(that))
33
+ }
34
+ }
35
+ common {
36
+ def unit = Z
37
+ }
38
+
26
39
def sum[T: Monoid](xs: List[T]): T =
27
40
(Monod.impl[T].unit /: xs)(_ `add` _)
28
41
*/
29
42
object runtime {
30
43
31
44
trait TypeClass {
32
- val common : TypeClassCommon
33
- type This = common .This
45
+ val commons : TypeClassCommon
46
+ type This = commons .This
34
47
}
35
48
36
49
trait TypeClassCommon { self =>
37
50
type This
38
51
type Instance <: TypeClass
39
- def inject (x : This ): Instance { val common : self.type }
52
+ def inject (x : This ): Instance { val commons : self.type }
40
53
}
41
54
42
55
trait TypeClassCompanion {
43
- type Impl [T ] <: Extension [ T ]
56
+ type Impl [T ] <: TypeClassCommon { type This = T }
44
57
def impl [T ](implicit ev : Impl [T ]): Impl [T ] = ev
45
58
}
46
59
47
- trait Extension [From ] extends TypeClassCommon {
48
- type This = From
49
- }
50
-
51
60
implicit def inject [From ](x : From )
52
- (implicit ev : Extension [ From ] ): ev.Instance { type This = From } =
61
+ (implicit ev : TypeClassCommon { type This = From } ): ev.Instance { type This = From } =
53
62
ev.inject(x)
54
63
}
55
64
import runtime ._
56
65
57
66
object semiGroups {
58
67
59
68
trait SemiGroup extends TypeClass {
60
- val common : SemiGroupCommon
61
- import common ._
69
+ val commons : SemiGroupCommon
70
+ import commons ._
62
71
def add (that : This ): This
63
72
}
64
73
trait SemiGroupCommon extends TypeClassCommon {
65
74
type Instance <: SemiGroup
66
75
}
67
76
object SemiGroup extends TypeClassCompanion {
68
- type Impl [T ] = Extension [ T ] with SemiGroupCommon
77
+ type Impl [T ] = SemiGroupCommon { type This = T }
69
78
}
70
79
71
80
trait Monoid extends SemiGroup {
72
- val common : MonoidCommon
73
- import common ._
81
+ val commons : MonoidCommon
82
+ import commons ._
74
83
}
75
84
trait MonoidCommon extends SemiGroupCommon {
76
85
type Instance <: Monoid
77
86
def unit : This
78
87
}
79
88
object Monoid extends TypeClassCompanion {
80
- type Impl [T ] = Extension [ T ] with MonoidCommon
89
+ type Impl [T ] = MonoidCommon { type This = T }
81
90
}
82
91
83
- implicit object IntOps extends Extension [ Int ] with MonoidCommon {
92
+ implicit object IntOps extends MonoidCommon {
84
93
type This = Int
85
94
type Instance = Monoid
86
95
def unit : Int = 0
87
96
def inject ($this : Int ) = new Monoid {
88
- val common : IntOps .this .type = IntOps .this
97
+ val commons : IntOps .this .type = IntOps .this
89
98
def add (that : This ): This = $this + that
90
99
}
91
100
}
92
101
93
- implicit object StringOps extends Extension [ String ] with MonoidCommon {
102
+ implicit object StringOps extends MonoidCommon {
94
103
type This = String
95
104
type Instance = Monoid
96
105
def unit = " "
97
106
def inject ($this : String ) = new Monoid {
98
- val common : StringOps .this .type = StringOps .this
107
+ val commons : StringOps .this .type = StringOps .this
99
108
def add (that : This ): This = $this .concat(that)
100
109
}
101
110
}
102
111
112
+ enum Nat extends Monoid {
113
+ case Z
114
+ case S (n : Nat )
115
+
116
+ def add (that : Nat ): Nat = this match {
117
+ case Z => that
118
+ case S (n) => S (n.add(that))
119
+ }
120
+
121
+ val commons : Nat .type = Nat
122
+ }
123
+ object Nat extends MonoidCommon {
124
+ type This = Nat
125
+ type Instance = Nat
126
+ def unit = Nat .Z
127
+ def inject ($this : Nat ) = $this
128
+ }
129
+ import Nat .{Z , S }
130
+
131
+ implicit def NatOps : Nat .type = Nat
132
+
103
133
def sum [T ](xs : List [T ])(implicit ev : Monoid .Impl [T ]) =
104
134
(Monoid .impl[T ].unit /: xs)((x, y) => x `add` y)
135
+
136
+ sum(List (1 , 2 , 3 ))
137
+ sum(List (" hello " , " world!" ))
138
+ sum(List (Z , S (Z ), S (S (Z ))))
105
139
}
106
140
107
- /** Encoding for
141
+ /** 2. Generic implementations of simple type classes.
108
142
109
143
trait Ord extends TypeClass {
110
144
def compareTo(that: This): Int
@@ -144,8 +178,8 @@ object semiGroups {
144
178
object ord {
145
179
146
180
trait Ord extends TypeClass {
147
- val common : OrdCommon
148
- import common ._
181
+ val commons : OrdCommon
182
+ import commons ._
149
183
def compareTo (that : This ): Int
150
184
def < (that : This ) = compareTo(that) < 0
151
185
def > (that : This ) = compareTo(that) > 0
@@ -155,27 +189,28 @@ object ord {
155
189
def minimum : This
156
190
}
157
191
object Ord extends TypeClassCompanion {
158
- type Impl [T ] = Extension [ T ] with OrdCommon
192
+ type Impl [T ] = OrdCommon { type This = T }
159
193
}
160
194
161
- implicit object IntOrd extends Extension [ Int ] with OrdCommon {
195
+ implicit object IntOrd extends OrdCommon {
162
196
type This = Int
163
197
type Instance = Ord
164
198
val minimum : Int = Int .MinValue
165
199
def inject ($this : Int ) = new Ord {
166
- val common : IntOrd .this .type = IntOrd .this
200
+ val commons : IntOrd .this .type = IntOrd .this
201
+ import commons ._
167
202
def compareTo (that : This ): Int =
168
203
if (this < that) - 1 else if (this > that) + 1 else 0
169
204
}
170
205
}
171
206
172
- class ListOrd [T ](implicit ev : Ord .Impl [T ])
173
- extends Extension [List [T ]] with OrdCommon { self =>
207
+ class ListOrd [T ](implicit ev : Ord .Impl [T ]) extends OrdCommon { self =>
174
208
type This = List [T ]
175
209
type Instance = Ord
176
210
def minimum : List [T ] = Nil
177
211
def inject ($this : List [T ]) = new Ord {
178
- val common : self.type = self
212
+ val commons : self.type = self
213
+ import commons ._
179
214
def compareTo (that : List [T ]): Int = ($this , that) match {
180
215
case (Nil , Nil ) => 0
181
216
case (Nil , _) => - 1
@@ -197,9 +232,13 @@ object ord {
197
232
val smallest = Ord .impl[T ].minimum
198
233
(smallest /: xs)(min)
199
234
}
235
+
236
+ inf(List [Int ]())
237
+ inf(List (List (1 , 2 ), List (1 , 2 , 3 )))
238
+ inf(List (List (List (1 ), List (2 )), List (List (1 ), List (2 ), List (3 ))))
200
239
}
201
240
202
- /** Encoding for
241
+ /** 3. Higher-kinded type classes
203
242
204
243
trait Functor[A] extends TypeClass1 {
205
244
def map[B](f: A => B): This[B]
@@ -234,75 +273,74 @@ object ord {
234
273
object runtime1 {
235
274
236
275
trait TypeClass1 {
237
- val common : TypeClassCommon1
238
- type This = common .This
276
+ val commons : TypeClassCommon1
277
+ type This = commons .This
239
278
}
240
279
241
280
trait TypeClassCommon1 { self =>
242
281
type This [X ]
243
282
type Instance [X ] <: TypeClass1
244
- def inject [A ](x : This [A ]): Instance [A ] { val common : self.type }
283
+ def inject [A ](x : This [A ]): Instance [A ] { val commons : self.type }
245
284
}
246
285
247
286
trait TypeClassCompanion1 {
248
- type Impl [T [_]] <: Extension1 [ T ]
287
+ type Impl [T [_]] <: TypeClassCommon1 { type This = T }
249
288
def impl [T [_]](implicit ev : Impl [T ]): Impl [T ] = ev
250
289
}
251
290
252
- trait Extension1 [From [_]] extends TypeClassCommon1 {
253
- type This [X ] = From [X ]
254
- }
255
-
256
291
implicit def inject1 [A , From [_]](x : From [A ])
257
- (implicit ev : Extension1 [ From ] ): ev.Instance [A ] { type This = From } =
292
+ (implicit ev : TypeClassCommon1 { type This = From } ): ev.Instance [A ] { type This = From } =
258
293
ev.inject(x)
259
294
}
260
295
import runtime1 ._
261
296
262
297
object functors {
263
298
264
299
trait Functor [A ] extends TypeClass1 {
265
- val common : FunctorCommon
266
- import common ._
300
+ val commons : FunctorCommon
301
+ import commons ._
267
302
def map [B ](f : A => B ): This [B ]
268
303
}
269
304
trait FunctorCommon extends TypeClassCommon1 {
270
305
type Instance [X ] <: Functor [X ]
271
306
def pure [A ](x : A ): This [A ]
272
307
}
273
308
object Functor extends TypeClassCompanion1 {
274
- type Impl [T [_]] = Extension1 [ T ] with FunctorCommon
309
+ type Impl [T [_]] = FunctorCommon { type This = T }
275
310
}
276
311
277
312
trait Monad [A ] extends Functor [A ] {
278
- val common : MonadCommon
279
- import common ._
313
+ val commons : MonadCommon
314
+ import commons ._
280
315
def flatMap [B ](f : A => This [B ]): This [B ]
281
- def map [B ](f : A => B ) = this .flatMap(f.andThen(common .pure))
316
+ def map [B ](f : A => B ) = this .flatMap(f.andThen(commons .pure))
282
317
}
283
318
trait MonadCommon extends FunctorCommon {
284
319
type Instance [X ] <: Monad [X ]
285
320
}
286
321
object Monad extends TypeClassCompanion1 {
287
- type Impl [T [_]] = Extension1 [ T ] with MonadCommon
322
+ type Impl [T [_]] = MonadCommon { type This = T }
288
323
}
289
324
290
325
def develop [A , F [X ]](n : Int , x : A , f : A => A )(implicit ev : Functor .Impl [F ]): F [A ] =
291
326
if (n == 0 ) Functor .impl[F ].pure(x)
292
327
else develop(n - 1 , x, f).map(f)
293
328
294
- implicit object ListMonad extends Extension1 [ List ] with MonadCommon {
295
- type This [ A ] = List [ A ]
329
+ implicit object ListMonad extends MonadCommon {
330
+ type This = List
296
331
type Instance = Monad
297
332
def pure [A ](x : A ) = x :: Nil
298
333
def inject [A ]($this : List [A ]) = new Monad [A ] {
299
- val common : ListMonad .this .type = ListMonad
334
+ val commons : ListMonad .this .type = ListMonad
335
+ import commons ._
300
336
def flatMap [B ](f : A => List [B ]): List [B ] = $this .flatMap(f)
301
337
}
302
338
}
303
339
304
340
object MonadFlatten {
305
- def flatten [T [_], A ]($this : T [T [A ]])(implicit ev : Monad .Impl [T ]): T [A ] =
341
+ def flattened [T [_], A ]($this : T [T [A ]])(implicit ev : Monad .Impl [T ]): T [A ] =
306
342
$this .flatMap(identity )
307
343
}
344
+
345
+ MonadFlatten .flattened(List (List (1 , 2 , 3 ), List (4 , 5 )))
308
346
}
0 commit comments