11/** A possible type class encoding for
22
3- trait SemiGroup {
4- def add(that: This): This
5- }
6-
7- trait Monoid extends SemiGroup
8- common {
9- def unit: This
10- }
3+ trait SemiGroup extends TypeClass {
4+ def add(that: This): This
5+ }
116
12- extension IntOps for Int : Monoid {
13- def add(that: Int) = this + that
14- }
15- common {
16- def unit = 0
17- }
7+ trait Monoid extends SemiGroup
8+ common {
9+ def unit: This
10+ }
1811
19- extension StringOps for String : Monoid {
20- def add(that: Int) = this + + that
21- }
22- common {
23- def unit = ""
24- }
12+ extension IntOps for Int : Monoid {
13+ def add(that: Int) = this + that
14+ }
15+ common {
16+ def unit = 0
17+ }
2518
26- def sum[T: Monoid](xs: List[T]): T =
27- (instance[T, Monoid].unit /: xs)(_ `add` _)
19+ extension StringOps for String : Monoid {
20+ def add(that: Int) = this ++ that
21+ }
22+ common {
23+ def unit = ""
24+ }
2825
26+ def sum[T: Monoid](xs: List[T]): T =
27+ (Monod.impl[T].unit /: xs)(_ `add` _)
2928*/
3029object runtime {
3130
@@ -40,6 +39,11 @@ object runtime {
4039 def inject (x : This ): Instance { val common : self.type }
4140 }
4241
42+ trait TypeClassCompanion {
43+ type Impl [T ] <: Extension [T , _]
44+ def impl [T ](implicit ev : Impl [T ]): Impl [T ] = ev
45+ }
46+
4347 trait Extension [From , To <: TypeClass ] extends TypeClassCommon {
4448 type This = From
4549 type Instance = To
@@ -54,12 +58,16 @@ import runtime._
5458object semiGroups {
5559
5660 trait SemiGroup extends TypeClass {
61+ val common : SemiGroupCommon
5762 import common ._
5863 def add (that : This ): This
5964 }
6065 trait SemiGroupCommon extends TypeClassCommon {
6166 type Instance <: SemiGroup
6267 }
68+ object SemiGroup extends TypeClassCompanion {
69+ type Impl [T ] = Extension [T , SemiGroup ] with SemiGroupCommon
70+ }
6371
6472 trait Monoid extends SemiGroup {
6573 val common : MonoidCommon
@@ -69,6 +77,9 @@ object semiGroups {
6977 type Instance <: Monoid
7078 def unit : This
7179 }
80+ object Monoid extends TypeClassCompanion {
81+ type Impl [T ] = Extension [T , Monoid ] with MonoidCommon
82+ }
7283
7384 implicit object IntOps extends Extension [Int , Monoid ] with MonoidCommon { self =>
7485 type This = Int
@@ -90,51 +101,51 @@ object semiGroups {
90101 }
91102 }
92103
93- def sum [T ](xs : List [T ])(implicit $ev : Extension [ T , Monoid ] with MonoidCommon ) =
94- (implicitly[ Extension [ T , Monoid ] with MonoidCommon ].unit /: xs)((x, y) => x `add` y)
104+ def sum [T ](xs : List [T ])(implicit $ev : Monoid . Impl [ T ] ) =
105+ (Monoid .impl[ T ].unit /: xs)((x, y) => x `add` y)
95106}
96107
97108/** Encoding for
98109
99- trait Ord {
100- def compareTo(that: This): Int
101- def < (that: This) = compareTo(that) < 0
102- def > (that: This) = compareTo(that) > 0
103- }
104- common {
105- val minimum: This
106- }
110+ trait Ord extends TypeClass {
111+ def compareTo(that: This): Int
112+ def < (that: This) = compareTo(that) < 0
113+ def > (that: This) = compareTo(that) > 0
114+ }
115+ common {
116+ val minimum: This
117+ }
107118
108- extension IntOrd for Int : Ord {
109- def compareTo(that: Int) =
110- if (this < that) -1 else if (this > that) +1 else 0
111- }
112- common {
113- val minimum = Int.MinValue
114- }
119+ extension IntOrd for Int : Ord {
120+ def compareTo(that: Int) =
121+ if (this < that) -1 else if (this > that) +1 else 0
122+ }
123+ common {
124+ val minimum = Int.MinValue
125+ }
115126
116- extension ListOrd[T : Ord] for List[T] : Ord {
117- def compareTo(that: List[T]): Int = (this, that) match {
118- case (Nil, Nil) => 0
119- case (Nil, _) => -1
120- case (_, Nil) => +1
121- case (x :: xs, y :: ys) =>
122- val fst = x.compareTo(y)
123- if (fst != 0) fst else xs.compareTo(ys)
127+ extension ListOrd[T : Ord] for List[T] : Ord {
128+ def compareTo(that: List[T]): Int = (this, that) match {
129+ case (Nil, Nil) => 0
130+ case (Nil, _) => -1
131+ case (_, Nil) => +1
132+ case (x :: xs, y :: ys) =>
133+ val fst = x.compareTo(y)
134+ if (fst != 0) fst else xs.compareTo(ys)
135+ }
136+ }
137+ common {
138+ val minimum = Nil
124139 }
125- }
126- common {
127- val minimum = Nil
128- }
129140
130- def min[T: Ord](x: T, y: T) = if (x < y) x else y
141+ def min[T: Ord](x: T, y: T) = if (x < y) x else y
131142
132- def inf[T: Ord](xs: List[T]): T = (instance[T, Ord ].minimum /: xs)(_ ` min` _ )
143+ def inf[T: Ord](xs: List[T]): T = (Ord.impl[T ].minimum /: xs)(min)
133144*/
134-
135145object ord {
136146
137147 trait Ord extends TypeClass {
148+ val common : OrdCommon
138149 import common ._
139150 def compareTo (that : This ): Int
140151 def < (that : This ) = compareTo(that) < 0
@@ -144,6 +155,9 @@ object ord {
144155 type Instance <: Ord
145156 def minimum : This
146157 }
158+ object Ord extends TypeClassCompanion {
159+ type Impl [T ] = Extension [T , Ord ] with OrdCommon
160+ }
147161
148162 implicit object IntOrd extends Extension [Int , Ord ] with OrdCommon { self =>
149163 type This = Int
@@ -156,7 +170,7 @@ object ord {
156170 }
157171 }
158172
159- class ListOrd [T ](implicit ev : Extension [ T , Ord ] with OrdCommon )
173+ class ListOrd [T ](implicit ev : Ord . Impl [ T ] )
160174 extends Extension [List [T ], Ord ] with OrdCommon { self =>
161175 type This = List [T ]
162176 type Instance = Ord
@@ -174,14 +188,123 @@ object ord {
174188 }
175189 }
176190
177- implicit def listOrd [T ](implicit ev : Extension [ T , Ord ] with OrdCommon ): ListOrd [T ] =
191+ implicit def listOrd [T ](implicit ev : Ord . Impl [ T ] ): ListOrd [T ] =
178192 new ListOrd [T ]
179193
180- def min [T ](x : T , y : T )(implicit ev : Extension [ T , Ord ] with OrdCommon ): T =
194+ def min [T ](x : T , y : T )(implicit ev : Ord . Impl [ T ] ): T =
181195 if (x < y) x else y
182196
183- def inf [T ](xs : List [T ])(implicit ev : Extension [T , Ord ] with OrdCommon ): T = {
184- val smallest = implicitly[Extension [T , Ord ] with OrdCommon ].minimum
185- (smallest /: xs)(min(_, _))
197+ def inf [T ](xs : List [T ])(implicit ev : Ord .Impl [T ]): T = {
198+ val smallest = Ord .impl[T ].minimum
199+ (smallest /: xs)(min)
200+ }
201+ }
202+
203+ /** Encoding for
204+
205+ trait Functor[A] extends TypeClass1 {
206+ def map[B](f: A => B): This[B]
207+ }
208+ common {
209+ def pure[A](x: A): This[A]
210+ }
211+
212+ // Generically, `pure[A]{.map(f)}^n`
213+ def develop[A, F[X] : Functor[X]](n: Int, f: A => A): F[A] =
214+ if (n == 0) Functor.impl[F].pure[A]
215+ else develop[A, F](n - 1, f).map(f)
216+
217+ trait Monad[A] extends Functor[A] {
218+ def flatMap[B](f: A => This[B]): This[B]
219+ def map[B](f: A => B) = this.flatMap(f.andThen(pure))
220+ }
221+
222+ extension ListMonad[T] for List[T] : Monad[T] {
223+ static def pure[A] = Nil
224+
225+ def flatMap[B](f: A => List[B]): List[B] = this match {
226+ case x :: xs => f(x) ++ xs.flatMap(f)
227+ case Nil => Nil
228+ }
229+ }
230+
231+ extension MonadFlatten[T[X]: Monad[X]] for T[T[A]] {
232+ def flatten: T[A] = this.flatMap(identity)
233+ }
234+ */
235+ object runtime1 {
236+
237+ trait TypeClass1 {
238+ val common : TypeClassCommon1
239+ type This = common.This
240+ }
241+
242+ trait TypeClassCommon1 { self =>
243+ type This [X ]
244+ type Instance [X ] <: TypeClass1
245+ def inject [A ](x : This [A ]): Instance [A ] { val common : self.type }
246+ }
247+
248+ trait TypeClassCompanion1 {
249+ type Impl [T [_]] <: Extension1 [T , _]
250+ def impl [T [_]](implicit ev : Impl [T ]): Impl [T ] = ev
251+ }
252+
253+ trait Extension1 [From [_], To [X ] <: TypeClass1 ] extends TypeClassCommon1 {
254+ type This [X ] = From [X ]
255+ type Instance [X ] = To [X ]
256+ }
257+
258+ implicit def inject1 [A , From [_]](x : From [A ])
259+ (implicit ev : Extension1 [From , _]): ev.Instance [A ] { type This = From } =
260+ ev.inject(x)
261+ }
262+ import runtime1 ._
263+
264+ object functors {
265+
266+ trait Functor [A ] extends TypeClass1 {
267+ val common : FunctorCommon
268+ import common ._
269+ def map [B ](f : A => B ): This [B ]
270+ }
271+ trait FunctorCommon extends TypeClassCommon1 {
272+ type Instance [X ] <: Functor [X ]
273+ def pure [A ](x : A ): This [A ]
274+ }
275+ object Functor extends TypeClassCompanion1 {
276+ type Impl [T [_]] = Extension1 [T , Functor ] with FunctorCommon
277+ }
278+
279+ trait Monad [A ] extends Functor [A ] {
280+ val common : MonadCommon
281+ import common ._
282+ def flatMap [B ](f : A => This [B ]): This [B ]
283+ def map [B ](f : A => B ) = this .flatMap(f.andThen(common.pure))
284+ }
285+ trait MonadCommon extends FunctorCommon {
286+ type Instance [X ] <: Monad [X ]
287+ }
288+ object Monad extends TypeClassCompanion1 {
289+ type Impl [T [_]] = Extension1 [T , Monad ] with MonadCommon
290+ }
291+
292+ def develop [A , F [X ]](n : Int , x : A , f : A => A )(implicit ev : Functor .Impl [F ]): F [A ] =
293+ if (n == 0 ) Functor .impl[F ].pure(x)
294+ else develop(n - 1 , x, f).map(f)
295+
296+ implicit object ListMonad extends Extension1 [List , Monad ] with MonadCommon { self =>
297+ type This [A ] = List [A ]
298+ type Instance = Monad
299+ def pure [A ](x : A ) = x :: Nil
300+ def inject [A ]($this : List [A ]) = new Monad [A ] {
301+ val common : self.type = self
302+ def flatMap [B ](f : A => List [B ]): List [B ] = $this .flatMap(f)
303+ }
304+ }
305+
306+ object MonadFlatten {
307+ def flatten [T [_], A ]($this : T [T [A ]])(implicit ev : Monad .Impl [T ]): T [A ] =
308+ $this .flatMap(identity )
186309 }
187310}
0 commit comments