File tree 2 files changed +43
-0
lines changed
2 files changed +43
-0
lines changed Original file line number Diff line number Diff line change
1
+ //> using options -language:experimental.modularity -source future
2
+ trait TupleOf [+ A ]:
3
+ type Self
4
+ type Mapped [+ A ] <: Tuple
5
+ def map [B ](x : Self )(f : A => B ): Mapped [B ]
6
+
7
+ object TupleOf :
8
+
9
+ given EmptyTuple is TupleOf [Nothing ]:
10
+ type Mapped [+ A ] = EmptyTuple
11
+ def map [B ](x : EmptyTuple )(f : Nothing => B ): Mapped [B ] = x
12
+
13
+ given [A , Rest <: Tuple : TupleOf [A ]] => A *: Rest is TupleOf [A ]:
14
+ type Mapped [+ A ] = A *: Rest .Mapped [A ]
15
+ def map [B ](x : A *: Rest )(f : A => B ): Mapped [B ] =
16
+ (f(x.head) *: Rest .map(x.tail)(f))
17
+
18
+ def foo [T : TupleOf [Int ]](xs : T ): T .Mapped [Int ] = T .map(xs)(_ + 1 )
19
+
20
+ @ main def test =
21
+ foo(EmptyTuple ): EmptyTuple // ok
22
+ foo(1 *: EmptyTuple ): Int *: EmptyTuple // now also ok
Original file line number Diff line number Diff line change
1
+ //> using options -language:experimental.modularity -source future
2
+ infix abstract class TupleOf [T , + A ]:
3
+ type Mapped [+ A ] <: Tuple
4
+ def map [B ](x : T )(f : A => B ): Mapped [B ]
5
+
6
+ object TupleOf :
7
+
8
+ given TupleOf [EmptyTuple , Nothing ] with
9
+ type Mapped [+ A ] = EmptyTuple
10
+ def map [B ](x : EmptyTuple )(f : Nothing => B ): Mapped [B ] = x
11
+
12
+ given [A , Rest <: Tuple ](using tracked val tup : Rest TupleOf A ): TupleOf [A *: Rest , A ] with
13
+ type Mapped [+ A ] = A *: tup.Mapped [A ]
14
+ def map [B ](x : A *: Rest )(f : A => B ): Mapped [B ] =
15
+ (f(x.head) *: tup.map(x.tail)(f))
16
+
17
+ def foo [T ](xs : T )(using tup : T TupleOf Int ): tup.Mapped [Int ] = tup.map(xs)(_ + 1 )
18
+
19
+ @ main def test =
20
+ foo(EmptyTuple ): EmptyTuple // ok
21
+ foo(1 *: EmptyTuple ): Int *: EmptyTuple // now also ok
You can’t perform that action at this time.
0 commit comments