- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Parameterising BuilderFactory by Coll rather than This
Mon, 2009-06-15, 12:20
Hi,
I'd like to be able to make it so that companions only have to define
an implicit builder rather than an implicit BuilderFactory and then
the implicit BuilderFactory would depend on the implicit Builder.
Unfortunately this runs into kindedness issues with the current
approach: The implicit builderToBuilderFactory method needs a number
of type parameters equal to the kindedness of the corresponding
collection (note: I'm finding that the way companions work is already
dealing quite badly with this. Is there anything that can be done to
fix that?)
One solution is that we have this Coll type in TraversableTemplate
which is always a normal type (e.g for List it's List[_]). Would it be
possible to parameterise BuilderFactory by that instead, or is there
something I'm missing that makes that not work properly? That way we
can define the implicit in Companion as
def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
BuilderFactory[Coll, T, CC[T]] = ...
Mon, 2009-06-15, 13:07
#2
Re: Parameterising BuilderFactory by Coll rather than This
ok. So there are two things, Builder and BuilderFactory.
Builder's have type
Builder[-From, +To];
BuilderFactories have type
BuilderFactory[This, -From, +To]
The purpose of a BuilderFactory is purely to supply builders. Under
the new scheme I'm working on for how they're constructed, Builders
are reusable so given a Builder[From, To] you can always get a
BuilderFactory[T, From, To] for any T. Therefore for a given T we
should be able to define
implicit def builderToBuilderFactory[From, To](implicit builder :
Builder[From, To]) = BuilderFactory[T, From, To](builder)
The problem is determining what T to use.
Currently the way builder factories are used approximates the
following (this isn't how the code actually works, but it conveys the
idea better than the actual code):
trait Traversable[+A]{
type This <: Traversable[A];
def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R = ...
}
I am proposing that the way it should work instead is
trait Traversable[+A]{
type Coll <: Traversable[_];
def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R = ...
}
The motivation for this is that otherwise sometimes
builderToBuilderFactory would need type parameters and sometimes it
wouldn't as the kindedness of the corresponding collection varies,
which makes it difficult to define it once in the Companion trait and
then have all collections inherit the correct behaviour for free.
2009/6/15 Adriaan Moors :
> Hi,
> I'd like to help out, but I'm having trouble understanding your email. Could
> you elaborate please?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:20 PM, David MacIver
> wrote:
>>
>> Hi,
>>
>> I'd like to be able to make it so that companions only have to define
>> an implicit builder rather than an implicit BuilderFactory and then
>> the implicit BuilderFactory would depend on the implicit Builder.
>> Unfortunately this runs into kindedness issues with the current
>> approach: The implicit builderToBuilderFactory method needs a number
>> of type parameters equal to the kindedness of the corresponding
>> collection (note: I'm finding that the way companions work is already
>> dealing quite badly with this. Is there anything that can be done to
>> fix that?)
>>
>> One solution is that we have this Coll type in TraversableTemplate
>> which is always a normal type (e.g for List it's List[_]). Would it be
>> possible to parameterise BuilderFactory by that instead, or is there
>> something I'm missing that makes that not work properly? That way we
>> can define the implicit in Companion as
>>
>> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> BuilderFactory[Coll, T, CC[T]] = ...
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>
Mon, 2009-06-15, 14:47
#3
Re: Parameterising BuilderFactory by Coll rather than This
Sorry, I still don't understand. I would say This and Coll both have kind * in your example, so what would change in BuilderFactory?
(To be exact, This has kind *(Nothing, Traversable[A]), and Coll has kind *(Nothing, Traversable[X] forSome {type X}), where the kind *(L, U) classifies the proper types that are a subtype of U and a supertype of L)
Also, wouldn't type inference be able to infer the T (assuming it's added to the list of type arguments of the method) that's unknown in the call to builderToBuilderFactory, based on the expected type of the BuilderFactory?
cheers,adriaan
On Mon, Jun 15, 2009 at 1:59 PM, David MacIver <david.maciver@gmail.com> wrote:
(To be exact, This has kind *(Nothing, Traversable[A]), and Coll has kind *(Nothing, Traversable[X] forSome {type X}), where the kind *(L, U) classifies the proper types that are a subtype of U and a supertype of L)
Also, wouldn't type inference be able to infer the T (assuming it's added to the list of type arguments of the method) that's unknown in the call to builderToBuilderFactory, based on the expected type of the BuilderFactory?
cheers,adriaan
On Mon, Jun 15, 2009 at 1:59 PM, David MacIver <david.maciver@gmail.com> wrote:
ok. So there are two things, Builder and BuilderFactory.
Builder's have type
Builder[-From, +To];
BuilderFactories have type
BuilderFactory[This, -From, +To]
The purpose of a BuilderFactory is purely to supply builders. Under
the new scheme I'm working on for how they're constructed, Builders
are reusable so given a Builder[From, To] you can always get a
BuilderFactory[T, From, To] for any T. Therefore for a given T we
should be able to define
implicit def builderToBuilderFactory[From, To](implicit builder :
Builder[From, To]) = BuilderFactory[T, From, To](builder)
The problem is determining what T to use.
Currently the way builder factories are used approximates the
following (this isn't how the code actually works, but it conveys the
idea better than the actual code):
trait Traversable[+A]{
type This <: Traversable[A];
def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R = ...
}
I am proposing that the way it should work instead is
trait Traversable[+A]{
type Coll <: Traversable[_];
def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R = ...
}
The motivation for this is that otherwise sometimes
builderToBuilderFactory would need type parameters and sometimes it
wouldn't as the kindedness of the corresponding collection varies,
which makes it difficult to define it once in the Companion trait and
then have all collections inherit the correct behaviour for free.
2009/6/15 Adriaan Moors <adriaan.moors@cs.kuleuven.be>:
> Hi,
> I'd like to help out, but I'm having trouble understanding your email. Could
> you elaborate please?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:20 PM, David MacIver <david.maciver@gmail.com>
> wrote:
>>
>> Hi,
>>
>> I'd like to be able to make it so that companions only have to define
>> an implicit builder rather than an implicit BuilderFactory and then
>> the implicit BuilderFactory would depend on the implicit Builder.
>> Unfortunately this runs into kindedness issues with the current
>> approach: The implicit builderToBuilderFactory method needs a number
>> of type parameters equal to the kindedness of the corresponding
>> collection (note: I'm finding that the way companions work is already
>> dealing quite badly with this. Is there anything that can be done to
>> fix that?)
>>
>> One solution is that we have this Coll type in TraversableTemplate
>> which is always a normal type (e.g for List it's List[_]). Would it be
>> possible to parameterise BuilderFactory by that instead, or is there
>> something I'm missing that makes that not work properly? That way we
>> can define the implicit in Companion as
>>
>> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> BuilderFactory[Coll, T, CC[T]] = ...
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
Mon, 2009-06-15, 15:47
#4
Re: Parameterising BuilderFactory by Coll rather than This
The problem isn't the kindedness of This vs. Coll. The problem is the
kind of the collection type.
The companion object needs to define a method that can create all
BuilderFactories of the right type. The problem is that in the current
implementation "the right type" has a number of type parameters which
depends on the kindedness of the collection.
So if I had something like
class DoubleVector { }
then BuilderFactory would have type
implicit def builderToFactory[T](builder : Builder[T, DoubleVector]) :
BuilderFactory[DoubleVector, T, DoubleVector] = ...
whereas with
class List[T]{}
it has to have type
implicit def builderToFactory[S, T](builder : Builder[T, List[T]]) :
BuilderFactory[List[S], T, List[T]] = ...
so the number of type parameters on builderToBuilderFactory is a
function of the kindedness of the collection.
In the version where instead we had
implicit def builderToFactory[T](builder : Builder[T, List[T]]) :
BuilderFactory[List[_], T, List[T]] = ...
it would not be.
2009/6/15 Adriaan Moors :
> Sorry, I still don't understand. I would say This and Coll both have kind *
> in your example, so what would change in BuilderFactory?
> (To be exact, This has kind *(Nothing, Traversable[A]), and Coll has kind
> *(Nothing, Traversable[X] forSome {type X}), where the kind *(L, U)
> classifies the proper types that are a subtype of U and a supertype of L)
>
> Also, wouldn't type inference be able to infer the T (assuming it's added to
> the list of type arguments of the method) that's unknown in the call
> to builderToBuilderFactory, based on the expected type of the
> BuilderFactory?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:59 PM, David MacIver
> wrote:
>>
>> ok. So there are two things, Builder and BuilderFactory.
>>
>> Builder's have type
>>
>> Builder[-From, +To];
>>
>> BuilderFactories have type
>>
>> BuilderFactory[This, -From, +To]
>>
>> The purpose of a BuilderFactory is purely to supply builders. Under
>> the new scheme I'm working on for how they're constructed, Builders
>> are reusable so given a Builder[From, To] you can always get a
>> BuilderFactory[T, From, To] for any T. Therefore for a given T we
>> should be able to define
>>
>> implicit def builderToBuilderFactory[From, To](implicit builder :
>> Builder[From, To]) = BuilderFactory[T, From, To](builder)
>>
>> The problem is determining what T to use.
>>
>> Currently the way builder factories are used approximates the
>> following (this isn't how the code actually works, but it conveys the
>> idea better than the actual code):
>>
>> trait Traversable[+A]{
>> type This <: Traversable[A];
>>
>> def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R =
>> ...
>> }
>>
>> I am proposing that the way it should work instead is
>>
>> trait Traversable[+A]{
>> type Coll <: Traversable[_];
>>
>> def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R =
>> ...
>> }
>>
>> The motivation for this is that otherwise sometimes
>> builderToBuilderFactory would need type parameters and sometimes it
>> wouldn't as the kindedness of the corresponding collection varies,
>> which makes it difficult to define it once in the Companion trait and
>> then have all collections inherit the correct behaviour for free.
>>
>> 2009/6/15 Adriaan Moors :
>> > Hi,
>> > I'd like to help out, but I'm having trouble understanding your email.
>> > Could
>> > you elaborate please?
>> > cheers,
>> > adriaan
>> >
>> > On Mon, Jun 15, 2009 at 1:20 PM, David MacIver
>> > wrote:
>> >>
>> >> Hi,
>> >>
>> >> I'd like to be able to make it so that companions only have to define
>> >> an implicit builder rather than an implicit BuilderFactory and then
>> >> the implicit BuilderFactory would depend on the implicit Builder.
>> >> Unfortunately this runs into kindedness issues with the current
>> >> approach: The implicit builderToBuilderFactory method needs a number
>> >> of type parameters equal to the kindedness of the corresponding
>> >> collection (note: I'm finding that the way companions work is already
>> >> dealing quite badly with this. Is there anything that can be done to
>> >> fix that?)
>> >>
>> >> One solution is that we have this Coll type in TraversableTemplate
>> >> which is always a normal type (e.g for List it's List[_]). Would it be
>> >> possible to parameterise BuilderFactory by that instead, or is there
>> >> something I'm missing that makes that not work properly? That way we
>> >> can define the implicit in Companion as
>> >>
>> >> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> >> BuilderFactory[Coll, T, CC[T]] = ...
>> >>
>> >>
>> >> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>> >
>> >
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>
I'd like to help out, but I'm having trouble understanding your email. Could you elaborate please?
cheers,adriaan
On Mon, Jun 15, 2009 at 1:20 PM, David MacIver <david.maciver@gmail.com> wrote: