1+ object Implementing_Tuples :
2+
3+ sealed trait Tup
4+ case class ConsTup [T , H <: Tup ](head : T , tail : H ) extends Tup
5+ case object EmptyTup extends Tup
6+
7+ val *: = ConsTup // for unapply
8+ type *: [H , T <: Tup ] = ConsTup [H , T ] // for type matching
9+ type EmptyTup = EmptyTup .type // for type matching
10+
11+ extension [H ](head : H )
12+ def *: [T <: Tup ](tail : T ) = ConsTup (head, tail)
13+
14+ type Fold [T <: Tup , Seed , F [_,_]] = T match
15+ case EmptyTup => Seed
16+ case h *: t => Fold [t, F [Seed , h], F ]
17+
18+ extension [T <: Tup ](v : T )
19+ def fold [Seed , F [_,_]](seed : Seed )(
20+ fn : [C , Acc ] => (C , Acc ) => F [C , Acc ]
21+ ): Fold [T , Seed , F ] =
22+ (v match
23+ case EmptyTup => seed
24+ case h *: t => t.fold(fn(h, seed))(fn)
25+ ).asInstanceOf [Fold [T , Seed , F ]]
26+
27+ extension [T <: Tup ](v : T ) def reversed : Tup =
28+ v.fold[EmptyTup , [C , Acc ] =>> Acc match {
29+ case h *: t => C *: h *: t
30+ }](EmptyTup )(
31+ [C , Acc ] => (c : C , acc : Acc ) => acc match
32+ case _@(_ *: _) => c *: acc // error
33+ )
34+
35+ @ main def testProperFold =
36+ val t = (1 *: '2' *: " foo" *: EmptyTup )
37+ val reversed : (String *: Char *: Int *: EmptyTup ) = t.reversed // error
38+ println(reversed)
39+
40+ end Implementing_Tuples
0 commit comments