@@ -5,14 +5,16 @@ import scala.language.implicitConversions
5
5
object twoface {
6
6
protected object std {
7
7
type Int = scala.Int
8
+ type Boolean = scala.Boolean
8
9
type String = java.lang.String
9
10
}
10
11
export TwoFace .Int .extensions ._
12
+ export TwoFace .Boolean .extensions ._
11
13
object TwoFace {
12
14
opaque type Int [T <: std.Int ] = std.Int
13
15
object Int {
14
16
// constructors
15
- protected def create [T <: std.Int ](value : std.Int ) : Int [T ] = value
17
+ protected [ TwoFace ] def create [T <: std.Int ](value : std.Int ) : Int [T ] = value
16
18
def apply [T <: std.Int & Singleton ](value : T ) : Int [T ] = create[T ](value)
17
19
// conversions
18
20
given fromValue [T <: std.Int & Singleton ] as Conversion [T , Int [T ]] = t => create[T ](t)
@@ -22,9 +24,32 @@ object twoface {
22
24
given toWideTwoFace [T <: std.Int ] as Conversion [Int [T ], Int [std.Int ]] = t => create[std.Int ](t)
23
25
// operations
24
26
object extensions {
25
- def [L <: std.Int , R <: std.Int ](left : Int [L ]) + (right : Int [R ]) : Int [int.+ [L , R ]] = create[int.+ [L , R ]](left + right)
27
+ def [L <: std.Int , R <: std.Int ](left : Int [L ]) + (right : Int [R ]) : Int [int.+ [L , R ]] = Int .create[int.+ [L , R ]](left + right)
28
+ def [L <: std.Int , R <: std.Int ](left : Int [L ]) - (right : Int [R ]) : Int [int.- [L , R ]] = Int .create[int.- [L , R ]](left - right)
29
+ def [L <: std.Int , R <: std.Int ](left : Int [L ]) === (right : Int [R ]) : Boolean [any.== [L , R ]] = Boolean .create[any.== [L , R ]](left == right)
26
30
}
27
31
}
32
+
33
+ opaque type Boolean [T <: std.Boolean ] = std.Boolean
34
+ object Boolean {
35
+ // constructors
36
+ protected [TwoFace ] def create [T <: std.Boolean ](value : std.Boolean ) : Boolean [T ] = value
37
+ def apply [T <: std.Boolean & Singleton ](value : T ) : Boolean [T ] = create[T ](value)
38
+ // conversions
39
+ given fromValue [T <: std.Boolean & Singleton ] as Conversion [T , Boolean [T ]] = t => create[T ](t)
40
+ given fromWideValue (using DummyImplicit ) as Conversion [std.Boolean , Boolean [std.Boolean ]] = t => create[std.Boolean ](t)
41
+ given toValue [T <: std.Boolean ](using ValueOf [T ]) as Conversion [Boolean [T ], T ] = _ => valueOf[T ]
42
+ given toWideValue [T <: std.Boolean ] as Conversion [Boolean [T ], std.Boolean ] = _.asInstanceOf [std.Boolean ]
43
+ given toWideTwoFace [T <: std.Boolean ] as Conversion [Boolean [T ], Boolean [std.Boolean ]] = t => create[std.Boolean ](t)
44
+ // operations
45
+ object extensions {
46
+ def [L <: std.Boolean , R <: std.Boolean ](left : Boolean [L ]) === (right : Boolean [R ]) : Boolean [any.== [L , R ]] = Boolean .create[any.== [L , R ]](left == right)
47
+ }
48
+ }
49
+ }
50
+
51
+ object Checked {
52
+ opaque type Int [T <: std.Int ] = std.Int
28
53
}
29
54
}
30
55
@@ -34,6 +59,8 @@ val oneCT = TwoFace.Int(1)
34
59
val one : Int = 1
35
60
val oneRT : TwoFace .Int [Int ] = TwoFace .Int (one)
36
61
62
+ val b : TwoFace .Boolean [true ] = oneCT === oneCT
63
+
37
64
val twoCT : TwoFace .Int [2 ] = oneCT + oneCT
38
65
val a = TwoFace .Int (1 ) + 1
39
66
val twoCT2 : TwoFace .Int [2 ] = a
@@ -52,6 +79,7 @@ val tfOne : TwoFace.Int[Int] = fromInt(one)
52
79
object Test {
53
80
class Vec [S <: Int ](val size : TwoFace .Int [S ]) {
54
81
@ infix def concat [RS <: Int ](that : Vec [RS ]) = new Vec (this .size + that.size)
82
+ // @infix def == [RS <: Int](that : Vec[RS]) = this.size === that.size
55
83
}
56
84
57
85
val one : Int = 1
@@ -60,7 +88,9 @@ object Test {
60
88
val v3 : Vec [3 ] = v1 concat v2
61
89
val v3a = v1 concat v2
62
90
val v3b : Vec [3 ] = v3a
91
+ // val b1 : true = v1 === v1
63
92
64
93
val vOne : Vec [Int ] = new Vec (one)
65
94
val vecs = for (i <- 1 to 3 ) yield (new Vec (i) concat v1)
66
95
}
96
+
0 commit comments