Skip to content

Commit c997f35

Browse files
committed
Hylolib: Use name of bound parameter for context bounds
1 parent 1693271 commit c997f35

File tree

3 files changed

+44
-54
lines changed

3 files changed

+44
-54
lines changed

tests/pos/hylolib-extract.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ given BitArray is Collection:
2323

2424
extension [Self: Value](self: Self)
2525
def neq(other: Self): Boolean = !self.eq(other)
26+
27+
extension [Self: Collection](self: Self)
28+
def elementsEqual[T: Collection { type Element = Self.Element } ](other: T): Boolean =
29+
???

tests/pos/hylolib/AnyCollection.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object AnyCollection {
1919
// and `anyValueIsValue` when the method is called on a collection of `Int`s. None of these
2020
// choices is even correct! Note also that the ambiguity is suppressed if the constructor of
2121
// `AnyValue` is declared with a context bound rather than an implicit parameter.
22-
given b.Position is Value = b.positionIsValue
22+
given b.Position is Value = b.Position
2323

2424
def start(): AnyValue =
2525
AnyValue(base.startPosition)

tests/pos/hylolib/Collection.scala

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
package hylo
33

44
/** A collection of elements accessible by their position. */
5-
trait Collection {
5+
trait Collection:
66
type Self
77

88
/** The type of the elements in the collection. */
99
type Element: Value
1010

1111
/** The type of a position in the collection. */
12-
type Position: Value as positionIsValue
12+
type Position: Value
1313

14-
extension (self: Self) {
14+
extension (self: Self)
1515

1616
/** Returns `true` iff `self` is empty. */
1717
def isEmpty: Boolean =
@@ -70,35 +70,25 @@ trait Collection {
7070
*/
7171
def isBefore(i: Position, j: Position): Boolean =
7272
val e = self.endPosition
73-
if (i.eq(e)) {
74-
false
75-
} else if (j.eq(e)) {
76-
true
77-
} else {
78-
def _isBefore(n: Position): Boolean =
79-
if (n.eq(j)) {
80-
true
81-
} else if (n.eq(e)) {
82-
false
83-
} else {
84-
_isBefore(self.positionAfter(n))
85-
}
86-
_isBefore(self.positionAfter(i))
87-
}
88-
89-
}
90-
91-
}
92-
93-
extension [Self: Collection as s](self: Self) {
73+
if i `eq` e then false
74+
else if j `eq` e then true
75+
else
76+
def recur(n: Position): Boolean =
77+
if n `eq` j then true
78+
else if n `eq` e then false
79+
else recur(self.positionAfter(n))
80+
recur(self.positionAfter(i))
81+
end Collection
82+
83+
extension [Self: Collection](self: Self) {
9484

9585
/** Returns the first element of `self` along with a slice containing the suffix after this
9686
* element, or `None` if `self` is empty.
9787
*
9888
* @complexity
9989
* O(1)
10090
*/
101-
def headAndTail: Option[(s.Element, Slice[Self])] =
91+
def headAndTail: Option[(Self.Element, Slice[Self])] =
10292
if (self.isEmpty) {
10393
None
10494
} else {
@@ -113,9 +103,9 @@ extension [Self: Collection as s](self: Self) {
113103
* @complexity
114104
* O(n) where n is the number of elements in `self`.
115105
*/
116-
def reduce[T](partialResult: T, combine: (T, s.Element) => T): T =
106+
def reduce[T](partialResult: T, combine: (T, Self.Element) => T): T =
117107
val e = self.endPosition
118-
def loop(p: s.Position, r: T): T =
108+
def loop(p: Self.Position, r: T): T =
119109
if (p.eq(e)) {
120110
r
121111
} else {
@@ -132,9 +122,9 @@ extension [Self: Collection as s](self: Self) {
132122
* @complexity
133123
* O(n) where n is the number of elements in `self`.
134124
*/
135-
def forEach(action: (s.Element) => Boolean): Boolean =
125+
def forEach(action: (Self.Element) => Boolean): Boolean =
136126
val e = self.endPosition
137-
def loop(p: s.Position): Boolean =
127+
def loop(p: Self.Position): Boolean =
138128
if (p.eq(e)) {
139129
true
140130
} else if (!action(self.at(p))) {
@@ -149,7 +139,7 @@ extension [Self: Collection as s](self: Self) {
149139
* @complexity
150140
* O(n) where n is the number of elements in `self`.
151141
*/
152-
def map[T: Value](transform: (s.Element) => T): HyArray[T] =
142+
def map[T: Value](transform: (Self.Element) => T): HyArray[T] =
153143
self.reduce(
154144
HyArray[T](),
155145
(r, e) => r.append(transform(e), assumeUniqueness = true)
@@ -160,9 +150,9 @@ extension [Self: Collection as s](self: Self) {
160150
* @complexity
161151
* O(n) where n is the number of elements in `self`.
162152
*/
163-
def filter(isIncluded: (s.Element) => Boolean): HyArray[s.Element] =
153+
def filter(isIncluded: (Self.Element) => Boolean): HyArray[Self.Element] =
164154
self.reduce(
165-
HyArray[s.Element](),
155+
HyArray[Self.Element](),
166156
(r, e) => if (isIncluded(e)) then r.append(e, assumeUniqueness = true) else r
167157
)
168158

@@ -171,15 +161,15 @@ extension [Self: Collection as s](self: Self) {
171161
* @complexity
172162
* O(n) where n is the number of elements in `self`.
173163
*/
174-
def containsWhere(predicate: (s.Element) => Boolean): Boolean =
164+
def containsWhere(predicate: (Self.Element) => Boolean): Boolean =
175165
self.firstPositionWhere(predicate) != None
176166

177167
/** Returns `true` if all elements in `self` satisfy `predicate`.
178168
*
179169
* @complexity
180170
* O(n) where n is the number of elements in `self`.
181171
*/
182-
def allSatisfy(predicate: (s.Element) => Boolean): Boolean =
172+
def allSatisfy(predicate: (Self.Element) => Boolean): Boolean =
183173
self.firstPositionWhere(predicate) == None
184174

185175
/** Returns the position of the first element of `self` satisfying `predicate`, or `None` if no
@@ -188,9 +178,9 @@ extension [Self: Collection as s](self: Self) {
188178
* @complexity
189179
* O(n) where n is the number of elements in `self`.
190180
*/
191-
def firstPositionWhere(predicate: (s.Element) => Boolean): Option[s.Position] =
181+
def firstPositionWhere(predicate: (Self.Element) => Boolean): Option[Self.Position] =
192182
val e = self.endPosition
193-
def loop(p: s.Position): Option[s.Position] =
183+
def loop(p: Self.Position): Option[Self.Position] =
194184
if (p.eq(e)) {
195185
None
196186
} else if (predicate(self.at(p))) {
@@ -205,7 +195,7 @@ extension [Self: Collection as s](self: Self) {
205195
* @complexity
206196
* O(n) where n is the number of elements in `self`.
207197
*/
208-
def minElement(isLessThan: (s.Element, s.Element) => Boolean): Option[s.Element] =
198+
def minElement(isLessThan: (Self.Element, Self.Element) => Boolean): Option[Self.Element] =
209199
self.leastElement(isLessThan)
210200

211201
// NOTE: I can't find a reasonable way to call this method.
@@ -214,36 +204,36 @@ extension [Self: Collection as s](self: Self) {
214204
* @complexity
215205
* O(n) where n is the number of elements in `self`.
216206
*/
217-
def minElement()(using s.Element is Comparable): Option[s.Element] =
207+
def minElement()(using Self.Element is Comparable): Option[Self.Element] =
218208
self.minElement(isLessThan = _ `lt` _)
219209

220210
/** Returns the maximum element in `self`, using `isGreaterThan` to compare elements.
221211
*
222212
* @complexity
223213
* O(n) where n is the number of elements in `self`.
224214
*/
225-
def maxElement(isGreaterThan: (s.Element, s.Element) => Boolean): Option[s.Element] =
215+
def maxElement(isGreaterThan: (Self.Element, Self.Element) => Boolean): Option[Self.Element] =
226216
self.leastElement(isGreaterThan)
227217

228218
/** Returns the maximum element in `self`.
229219
*
230220
* @complexity
231221
* O(n) where n is the number of elements in `self`.
232222
*/
233-
def maxElement()(using s.Element is Comparable): Option[s.Element] =
223+
def maxElement()(using Self.Element is Comparable): Option[Self.Element] =
234224
self.maxElement(isGreaterThan = _ `gt` _)
235225

236226
/** Returns the maximum element in `self`, using `isOrderedBefore` to compare elements.
237227
*
238228
* @complexity
239229
* O(n) where n is the number of elements in `self`.
240230
*/
241-
def leastElement(isOrderedBefore: (s.Element, s.Element) => Boolean): Option[s.Element] =
231+
def leastElement(isOrderedBefore: (Self.Element, Self.Element) => Boolean): Option[Self.Element] =
242232
if (self.isEmpty) {
243233
None
244234
} else {
245235
val e = self.endPosition
246-
def _least(p: s.Position, least: s.Element): s.Element =
236+
def _least(p: Self.Position, least: Self.Element): Self.Element =
247237
if (p.eq(e)) {
248238
least
249239
} else {
@@ -258,22 +248,18 @@ extension [Self: Collection as s](self: Self) {
258248

259249
}
260250

261-
extension [Self: Collection as s](self: Self)(
262-
using s.Element is Value
263-
) {
251+
extension [Self: Collection](self: Self)
264252

265253
/** Returns `true` if `self` contains the same elements as `other`, in the same order. */
266-
def elementsEqual[T](using o: T is Collection { type Element = s.Element })(other: T): Boolean =
267-
def loop(i: s.Position, j: o.Position): Boolean =
268-
if (i `eq` self.endPosition) {
254+
def elementsEqual[T: Collection { type Element = Self.Element } ](other: T): Boolean =
255+
def loop(i: Self.Position, j: T.Position): Boolean =
256+
if i `eq` self.endPosition then
269257
j `eq` other.endPosition
270-
} else if (j `eq` other.endPosition) {
258+
else if j `eq` other.endPosition then
271259
false
272-
} else if (self.at(i) `neq` other.at(j)) {
260+
else if self.at(i) `neq` other.at(j)then
273261
false
274-
} else {
262+
else
275263
loop(self.positionAfter(i), other.positionAfter(j))
276-
}
277264
loop(self.startPosition, other.startPosition)
278265

279-
}

0 commit comments

Comments
 (0)