On Fri, Jun 19, 2009 at 6:35 AM, Sean Reque <[email protected]> wrote:
>
> I am trying to write a generic function to do a on-to-one join between
> mapper objects in memory using a map. The function is as follows:
>
> def oneToOneJoin[PType <: LongKeyedMapper[PType] with IdPK,
> CType <: LongKeyedMapper[CType] with IdPK,
> CMetaType <: CType with LongKeyedMetaMapper
> [CType],
> FKType <: MappedLongForeignKey[PType, CType]]
> (parents: List[PType], metaMapper: CMetaType, keyGetter: (PType) =>
> FKType ):
> Map[Long, CType] = {
> (Map.empty[Long, CType] /: metaMapper.findAll(
> ByList(metaMapper.id, parents.map {p => keyGetter
> (p).is.longValue } ))
> ) {(accum, v) => accum + (v.id.longValue -> v) }
>
> This function compiles fine, but I can't use it! Here is the call
> site:
>
> Util.oneToOneJoin(runs, TestSubject, (tr: TestRun) => tr.testSubject
>
> where runs is of type List[TestRun]
>
> Here are the relevant class and object definitions. All the
> definitions are "by the book", meaning the exploring Lift book :).
> Each test run has one test subject.
>
> class TestSubject extends LongKeyedMapper[TestSubject] with IdPK {
> object TestSubject extends TestSubject with LongKeyedMetaMapper
> [TestSubject] {
> class TestRun extends LongKeyedMapper[TestRun] with IdPK {
> object testSubject extends MappedLongForeignKey(this,
> TestSubject)
> }
> object TestRun extends TestRun with LongKeyedMetaMapper[TestRun]
> with CRUDify[Long, TestRun] {
>
>
>
>
> I get an error that makes me think I'm coding in C++ with the boost
> library. Scala is inferring CType as Nothing, which is definitely not
> what I want.
>
> error: inferred type arguments
> [com.test_results.model.TestRun,Nothing,object
> com.test_results.model.TestSubject,object
> com.test_results.model.TestRun#testSubject] do not conform to method
> oneToOneJoin's type parameter bounds [PType <:
> net.liftweb.mapper.LongKeyedMapper[PType] with
> net.liftweb.mapper.IdPK,CType <: net.liftweb.mapper.LongKeyedMapper
> [CType] with net.liftweb.mapper.IdPK,CMetaType <: CType with
> net.liftweb.mapper.LongKeyedMetaMapper[CType],FKType <:
> net.liftweb.mapper.MappedLongForeignKey[PType,CType]]
> Util.oneToOneJoin(runs, TestSubject, (tr: TestRun) =>
> tr.testSubject)
>
> I cannot find any way to get the class of the TestSubject companion
> object, So I changed things slightly to create a MetaTestSubject and
> then tried to explicitly specify the type parameters to the
> oneToOneJoin function as shown below. MetaTestSubject is the supertype
> for the TestSubject companion object so that I can reference it's type
> explicitly.
>
> Util.oneToOneJoin[TestRun,
> TestSubject,
> MetaTestSubject,
> (TestRun) => MappedLongForeignKey[TestRun,
> TestSubject]
> ](runs, TestSubject, (tr: TestRun) => tr.testSubject)
>
> where MetaTestSubject and TestSubject are now defined as
> class MetaTestSubject extends TestSubject with LongKeyedMetaMapper
> [TestSubject]
> object TestSubject extends MetaTestSubject {
>
>
> When I specify the types to the oneToOneJoin function explicitly,
> Scala then just plain tells me that the types don't match with this
> error.
>
> error: type arguments
>
> [com.test_results.model.TestRun,com.test_results.model.TestSubject,com.test_results.model.MetaTestSubject,
> (com.test_results.model.TestRun) =>
> net.liftweb.mapper.MappedLongForeignKey
> [com.test_results.model.TestRun,com.test_results.model.TestSubject]]
> do not conform to method oneToOneJoin's type parameter bounds [PType
> <: net.liftweb.mapper.LongKeyedMapper[PType] with
> net.liftweb.mapper.IdPK,CType <: net.liftweb.mapper.LongKeyedMapper
> [CType] with net.liftweb.mapper.IdPK,CMetaType <: CType with
> net.liftweb.mapper.LongKeyedMetaMapper[CType],FKType <:
> net.liftweb.mapper.MappedLongForeignKey[PType,CType]]
> Util.oneToOneJoin[TestRun,
>
> After a couple of hours of trying I am stuck at this point and all of
> the types look like they line up to me. TestRun is a LongKeyedMapper
> of the right type with IdPK, and so is TestSubject. MetaTestSubject
> inherits from TestSubject with LongKeyedMetaMapper[TestSubject]. The
> third value parameter is a function takes a type TestRun and returns a
> MappedLongForeignKey[TestRun, TestSubject].
>
> What am I doing wrong?
In the second one where you explicitly specified the types, you are doing
nothing wrong.
In the first case, because there were no parameters with the type CType, the
type inferencer couldn't figure out what CType was. The type inferencer
only looks a certain number of levels for a type in order to avoid cyclical
type references and in order to save compilation speed.
> Is this a scala bug?
Yes.
I would suggest reporting it.
>
>
> - Sean Reque
>
> >
>
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---