Skip to content

Commit e36e7b4

Browse files
committed
pt6_UnionType
1 parent 9b373e5 commit e36e7b4

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

Diff for: src/main/scala/workshop/pt6_UnionType.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package workshop
2+
3+
object pt6_UnionType {
4+
5+
type Not[P] = P => Nothing
6+
infix type v[T, U] = Not[Not[T] & Not[U]]
7+
infix type |∨|[T, U] = [X] =>> Not[Not[X]] <:< (T v U)
8+
9+
}

Diff for: src/test/scala/workshop/pt6_UnionTypeSpec.scala

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package workshop
2+
3+
import org.scalatest.flatspec.AnyFlatSpec
4+
import org.scalatest.matchers.should.Matchers
5+
import workshop.pt6_UnionType.*
6+
7+
class pt6_UnionTypeSpec extends AnyFlatSpec with Matchers {
8+
9+
it should "types specified in union type are subtype of union type" in {
10+
assertCompiles("summon[Not[Not[Int]] <:< (Int v String)]")
11+
assertCompiles("summon[Not[Not[String]] <:< (Int v String)]")
12+
}
13+
14+
it should "types not specified in union type are not part of union type" in {
15+
assertDoesNotCompile("summon[Not[Not[Float]] <:< (Double v Int)]")
16+
assertDoesNotCompile("summon[Not[Not[String]] <:< (Double v Int)]")
17+
}
18+
19+
it should "verify union types using evidence at compile time" in {
20+
def size[T](t: T)(using Not[Not[T]] <:< (Int v String)) =
21+
t match {
22+
case i: Int => i
23+
case s: String => s.length
24+
}
25+
26+
assertCompiles("size(1)")
27+
assertCompiles("size(\"11\")")
28+
assertDoesNotCompile("size(1.0)")
29+
}
30+
31+
it should "verify union types using bounds at compile time" in {
32+
def size[T: (Int |∨| String)](t: T) =
33+
t match {
34+
case i: Int => i
35+
case s: String => s.length
36+
}
37+
38+
assertCompiles("size(1)")
39+
assertCompiles("size(\"11\")")
40+
assertDoesNotCompile("size(1.0)")
41+
}
42+
43+
}

0 commit comments

Comments
 (0)