@@ -3,17 +3,24 @@ package collection
3
3
4
4
import strawman .collection .mutable .Builder
5
5
6
- import scala .{Any , Int }
6
+ import scala .{Any , Int , Nothing }
7
7
import scala .annotation .unchecked .uncheckedVariance
8
8
9
9
/** Instances of Build[B] can build some kind of collection from values of type B. */
10
10
trait Build [- B ] {
11
11
type To [_]
12
12
def fromIterable [E <: B ](it : Iterable [E ]): To [E ]
13
13
}
14
+ trait BuildStrict [- B ] extends Build [B ] {
15
+ def newBuilder [E <: B ]: Builder [E , To [E ]]
16
+ }
14
17
18
+ /** Instances of BuildConstrained can build some kind of collection from values with an implicit constraint. */
15
19
trait BuildConstrained {
16
- trait Constraint [E ] extends Build [E ]
20
+ trait Constraint [E ] <: Build [E ]
21
+ }
22
+ trait BuildStrictConstrained extends BuildConstrained {
23
+ trait Constraint [E ] extends super .Constraint [E ] with BuildStrict [E ]
17
24
}
18
25
19
26
/** Base trait for instances that can construct a collection from an iterable */
@@ -24,12 +31,12 @@ trait FromIterable[+C[_]] extends Build[Any] {
24
31
25
32
/** Base trait for instances that can construct a collection from an iterable by using an implicit evidence
26
33
* for the element type. */
27
- trait ConstrainedFromIterable [+ CC [_], Ev [_]] {
34
+ trait ConstrainedFromIterable [+ CC [_], Ev [_]] extends BuildConstrained {
28
35
def constrainedFromIterable [E : Ev ](it : Iterable [E ]): CC [E ]
29
36
}
30
37
31
38
/** Base trait for companion objects of unconstrained collection types */
32
- trait IterableFactory [+ C [_]] extends FromIterable [C ] { self =>
39
+ trait IterableFactory [+ C [_]] extends FromIterable [C ] with BuildStrict [ Any ] { self =>
33
40
def empty [A ]: C [A ] = fromIterable(View .Empty )
34
41
35
42
def apply [A ](xs : A * ): C [A ] = fromIterable(View .Elems (xs : _* ))
@@ -38,21 +45,33 @@ trait IterableFactory[+C[_]] extends FromIterable[C] { self =>
38
45
39
46
def newBuilder [A ]: Builder [A , C [A ]]
40
47
41
- protected [this ] lazy val canBuildProto : CanBuild [Any , C [Any ]] = new CanBuild [Any , C [Any ]] {
42
- def fromIterable (it : Iterable [Any ]): C [Any ] = self.fromIterable[Any ](it)
43
- def newBuilder : Builder [Any , C [Any ]] = self.newBuilder[Any ]
48
+ protected [this ] lazy val buildFromProto : BuildFrom [C [Any ], Any ] = new BuildFrom [C [Any ], Any ] {
49
+ type To [_] = C [Any ]
50
+ def fromIterable [E ](it : Iterable [E ]): C [Any ] = self.fromIterable[Any ](it)
51
+ def newBuilder [E ]: Builder [E , C [Any ]] = self.newBuilder[Any ]
44
52
}
45
53
46
- implicit def canBuild [E ]: CanBuild [E , C [E ]] = canBuildProto.asInstanceOf [CanBuild [E , C [E ]]]
54
+ implicit def buildFrom [F , E ]: BuildFrom [C [F ], E ] { type To [_] <: C [E ] } =
55
+ buildFromProto.asInstanceOf [BuildFrom [C [F ], E ] { type To [_] <: C [E ] }]
56
+
57
+ def buildFromAny [E ]: BuildFrom [Nothing , E ] { type To [_] <: C [E ] } =
58
+ buildFromProto.asInstanceOf [BuildFrom [Nothing , E ] { type To [_] <: C [E ] }]
47
59
}
48
60
49
- trait CanBuild [ E , + Repr ] {
50
- def fromIterable ( it : Iterable [E ]) : Repr
51
- def newBuilder : Builder [ E , Repr ]
61
+ /** Implicit instances of this type are available for building arbitrary collection types */
62
+ trait BuildFrom [ + Repr , E ] extends BuildStrict [E ] { self =>
63
+ def any : BuildFrom [ Nothing , E ] { type To [ X ] = self. To [ X ] } = this . asInstanceOf [ BuildFrom [ Nothing , E ] { type To [ X ] = self. To [ X ] } ]
52
64
}
53
65
54
66
/** Base trait for companion objects of collections that require an implicit evidence */
55
- trait ConstrainedIterableFactory [+ CC [X ], Ev [_]] extends ConstrainedFromIterable [CC , Ev ] {
67
+ trait ConstrainedIterableFactory [+ CC [X ], Ev [_]] extends ConstrainedFromIterable [CC , Ev ] with BuildStrictConstrained {
68
+
69
+ class ConstraintImpl [E : Ev ] extends Constraint [E ] {
70
+ type To [_] = CC [E ] @ uncheckedVariance
71
+ def fromIterable [X <: E ](it : Iterable [X ]): CC [E ] = constrainedFromIterable[E ](it)
72
+ def newBuilder [X <: E ]: Builder [X , CC [E ]] = constrainedNewBuilder[E ]
73
+ }
74
+ implicit def constraint [E : Ev ]: ConstraintImpl [E ] = new ConstraintImpl [E ]
56
75
57
76
def empty [A : Ev ]: CC [A ] = constrainedFromIterable(View .Empty )
58
77
@@ -62,8 +81,12 @@ trait ConstrainedIterableFactory[+CC[X], Ev[_]] extends ConstrainedFromIterable[
62
81
63
82
def constrainedNewBuilder [A : Ev ]: Builder [A , CC [A ]]
64
83
65
- implicit def canBuild [E : Ev ]: CanBuild [E , CC [E ]] = new CanBuild [E , CC [E ]] {
66
- def fromIterable (it : Iterable [E ]): CC [E ] = constrainedFromIterable[E ](it)
67
- def newBuilder : Builder [E , CC [E ]] = constrainedNewBuilder[E ]
84
+ implicit def buildFrom [F , E : Ev ]: BuildFrom [CC [F ], E ] { type To [_] <: CC [E ] } = new BuildFrom [CC [F ], E ] {
85
+ type To [_] = CC [E ]
86
+ def fromIterable [X <: E ](it : Iterable [X ]): CC [E ] = constrainedFromIterable[E ](it)
87
+ def newBuilder [X <: E ]: Builder [X , CC [E ]] = constrainedNewBuilder[E ]
68
88
}
89
+
90
+ def buildFromAny [E : Ev ]: BuildFrom [Nothing , E ] { type To [_] <: CC [E ] } =
91
+ buildFrom[Any , E ].asInstanceOf [BuildFrom [Nothing , E ] { type To [_] <: CC [E ] }]
69
92
}
0 commit comments