1
1
// src/script/scala/progscala3/typesystem/matchtypes/MatchTypes2.scala
2
2
// Not in the book. More experimenting with match types.
3
+ import compiletime .asMatchable
4
+
3
5
type Elem [X <: Matchable ] = X match
4
6
case String => Char
5
7
case Array [t] => t
@@ -35,15 +37,16 @@ lastUnsafe(None)
35
37
// Does this parse and provide a safe implementation? No; it has trouble
36
38
// confirming that Char =:= Elem[String] for "s.last" and
37
39
// Matchable =:= Elem[Matchable] for the default Matchable clause.
38
- def lastOrElse [X <: Matchable ](in : X )(default : => Elem [X ]): Elem [X ] = in match
40
+
41
+ def lastOrElse [X <: Matchable ](in : X )(default : => Elem [X ]): Elem [X ] = in.asMatchable match
39
42
case s : String => if s.isEmpty then default else s.last
40
43
case a : Array [Elem [X ]] => if a.isEmpty then default else a.last
41
44
case i : Iterable [Elem [X ]] => if i.isEmpty then default else i.last
42
45
case o : Option [Elem [X ]] => o.getOrElse(default)
43
46
case m : Matchable => m
44
47
45
48
// What about using options? Same parsing problems...
46
- def lastOption [X <: Matchable ](in : X ): Option [Elem [X ]] = in match
49
+ def lastOption [X <: Matchable ](in : X ): Option [Elem [X ]] = in.asMatchable match
47
50
case s : String => s.lastOption
48
51
case a : Array [Elem [X ]] => a.lastOption
49
52
case i : Iterable [Elem [X ]] => i.lastOption
@@ -53,7 +56,7 @@ def lastOption[X <: Matchable](in: X): Option[Elem[X]] = in match
53
56
// Surely this will work, no? No; it seems that any attempt to combine the
54
57
// match type Elem[X] with other types, whether "| Null", Option[...], or
55
58
// using it as the type of a default argument fails to work.
56
- def lastOrNull [X <: Matchable ](in : X ): Elem [X ] | Null = in match
59
+ def lastOrNull [X <: Matchable ](in : X ): Elem [X ] | Null = in.asMatchable match
57
60
case s : String => if s.isEmpty then null else s.last
58
61
case a : Array [Elem [X ]] => if a.isEmpty then null else a.last
59
62
case i : Iterable [Elem [X ]] => if i.isEmpty then null else i.last
@@ -69,7 +72,7 @@ type RElem[X <: Matchable] = X match
69
72
case Option [t] => RElem [t]
70
73
case Matchable => X
71
74
72
- def rlastUnsafe [X <: Matchable ](in : X ): RElem [X ] = in match
75
+ def rlastUnsafe [X <: Matchable ](in : X ): RElem [X ] = in.asMatchable match
73
76
case s : String => s.last
74
77
case a : Array [t] => rlastUnsafe(a.last)
75
78
case i : Iterable [t] => rlastUnsafe(i.last)
@@ -83,21 +86,21 @@ def rlastUnsafe[X <: Matchable](in: X): RElem[X] = in match
83
86
// case o: Option[RElem[X]] => rlastOrElse(o.getOrElse(default))
84
87
// case a: Any => a
85
88
86
- def rlastOrElse [X ](in : X , default : RElem [X ]): RElem [X ] = in match
89
+ def rlastOrElse [X ](in : X , default : RElem [X ]): RElem [X ] = in.asMatchable match
87
90
case s : String => s.lastOption.getOrElse(default)
88
91
case a : Array [RElem [X ]] => rlastOrElse(a.lastOption.getOrElse(default))
89
92
case i : Iterable [RElem [X ]] => rlastOrElse(i.lastOption.getOrElse(default))
90
93
case o : Option [RElem [X ]] => rlastOrElse(o.getOrElse(default))
91
94
case a : Any => a
92
95
93
- def rlastOption [X ](in : X ): Option [RElem [X ]] = in match
96
+ def rlastOption [X ](in : X ): Option [RElem [X ]] = in.asMatchable match
94
97
case s : String => s.lastOption
95
98
case a : Array [RElem [X ]] => a.lastOption.flatMap(x => rlastOption(x))
96
99
case i : Iterable [RElem [X ]] => i.lastOption.flatMap(x => rlastOption(x))
97
100
case o : Option [RElem [X ]] => o.flatMap(x => rlastOption(x))
98
101
case a : Any => Some (a)
99
102
100
- def rlastOrNull [X ](in : X ): RElem [X ] | Null = in match
103
+ def rlastOrNull [X ](in : X ): RElem [X ] | Null = in.asMatchable match
101
104
case s : String => if s.isEmpty then null else s.last
102
105
case a : Array [RElem [X ]] => if a.isEmpty then null else rlastOrNull(a.last)
103
106
case i : Iterable [RElem [X ]] => if i.isEmpty then null else rlastOrNull(i.last)
0 commit comments