|
1 | | -object Logarithms { |
| 1 | +object MyMath: |
2 | 2 |
|
3 | 3 | opaque type Logarithm = Double |
4 | 4 |
|
5 | | - object Logarithm { |
| 5 | + object Logarithm: |
| 6 | + |
| 7 | + // These are the two ways to lift to the Logarithm type |
6 | 8 |
|
7 | | - // These are the ways to lift to the logarithm type |
8 | 9 | def apply(d: Double): Logarithm = math.log(d) |
9 | 10 |
|
10 | 11 | def safe(d: Double): Option[Logarithm] = |
11 | | - if (d > 0.0) Some(math.log(d)) else None |
12 | | - } |
| 12 | + if d > 0.0 then Some(math.log(d)) else None |
| 13 | + |
| 14 | + end Logarithm |
13 | 15 |
|
14 | 16 | // Extension methods define opaque types' public APIs |
15 | 17 | extension (x: Logarithm) |
16 | 18 | def toDouble: Double = math.exp(x) |
17 | 19 | def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y)) |
18 | 20 | def * (y: Logarithm): Logarithm = x + y |
19 | | -} |
20 | 21 |
|
21 | | -object LogTest { |
22 | | - import Logarithms.* |
| 22 | +end MyMath |
| 23 | + |
| 24 | +object LogTest: |
| 25 | + import MyMath.Logarithm |
23 | 26 | import Predef.{any2stringadd as _, *} |
24 | 27 |
|
25 | 28 | val l = Logarithm(1.0) |
26 | 29 | val l2 = Logarithm(2.0) |
27 | 30 | val l3 = l * l2 |
28 | 31 | val l4 = l + l2 |
29 | | -} |
30 | 32 |
|
31 | 33 |
|
32 | | -object Access { |
| 34 | + |
| 35 | +object Access: |
33 | 36 |
|
34 | 37 | opaque type Permissions = Int |
35 | 38 | opaque type PermissionChoice = Int |
36 | 39 | opaque type Permission <: Permissions & PermissionChoice = Int |
37 | 40 |
|
38 | | - extension (x: Permissions) |
39 | | - def & (y: Permissions): Permissions = x | y |
40 | 41 | extension (x: PermissionChoice) |
41 | 42 | def | (y: PermissionChoice): PermissionChoice = x | y |
| 43 | + extension (x: Permissions) |
| 44 | + def & (y: Permissions): Permissions = x | y |
42 | 45 | extension (granted: Permissions) |
43 | 46 | def is(required: Permissions) = (granted & required) == required |
44 | | - extension (granted: Permissions) |
45 | 47 | def isOneOf(required: PermissionChoice) = (granted & required) != 0 |
46 | 48 |
|
47 | 49 | val NoPermission: Permission = 0 |
48 | 50 | val Read: Permission = 1 |
49 | 51 | val Write: Permission = 2 |
50 | 52 | val ReadWrite: Permissions = Read | Write |
51 | 53 | val ReadOrWrite: PermissionChoice = Read | Write |
52 | | -} |
53 | 54 |
|
54 | | -object User { |
| 55 | +end Access |
| 56 | + |
| 57 | +object User: |
55 | 58 | import Access.* |
56 | 59 |
|
57 | 60 | case class Item(rights: Permissions) |
| 61 | + extension (item: Item) |
| 62 | + def +(other: Item): Item = Item(item.rights & other.rights) |
58 | 63 |
|
59 | 64 | val roItem = Item(Read) // OK, since Permission <: Permissions |
| 65 | + val woItem = Item(Write) |
60 | 66 | val rwItem = Item(ReadWrite) |
61 | 67 | val noItem = Item(NoPermission) |
62 | 68 |
|
63 | | - assert( roItem.rights.is(ReadWrite) == false ) |
64 | | - assert( roItem.rights.isOneOf(ReadOrWrite) == true ) |
| 69 | + assert(!roItem.rights.is(ReadWrite)) |
| 70 | + assert(roItem.rights.isOneOf(ReadOrWrite)) |
65 | 71 |
|
66 | | - assert( rwItem.rights.is(ReadWrite) == true ) |
67 | | - assert( rwItem.rights.isOneOf(ReadOrWrite) == true ) |
| 72 | + assert(rwItem.rights.is(ReadWrite)) |
| 73 | + assert(rwItem.rights.isOneOf(ReadOrWrite)) |
68 | 74 |
|
69 | | - assert( noItem.rights.is(ReadWrite) == false ) |
70 | | - assert( noItem.rights.isOneOf(ReadOrWrite) == false ) |
| 75 | + assert(!noItem.rights.is(ReadWrite)) |
| 76 | + assert(!noItem.rights.isOneOf(ReadOrWrite)) |
71 | 77 |
|
| 78 | + assert((roItem + woItem).rights.is(ReadWrite)) |
72 | 79 | // Would be a type error: |
73 | | - // assert( roItem.rights.isOneOf(ReadWrite) == true ) |
74 | | -} |
| 80 | + // assert(roItem.rights.isOneOf(ReadWrite)) |
| 81 | +end User |
75 | 82 |
|
76 | 83 | object o { |
77 | 84 | opaque type T = Int |
|
0 commit comments