Help with recursive "MyType" in 2.10

81 views
Skip to first unread message

Naftoli Gugenheim

unread,
Nov 22, 2012, 1:32:04 AM11/22/12
to scala-l...@googlegroups.com
Hi, I'm trying to get lift-squeryl-record to compile on 2.10. It compiles on 2.9.x. Here's the relevant code:

trait Record[MyType <: Record[MyType]] extends FieldContainer {
  self: MyType =>
...
  def meta: MetaRecord[MyType]
...
  def fieldByName(fieldName: String): Box[Field[_, MyType]] = meta.fieldByName(fieldName, this)
...
}

trait MetaRecord[BaseRecord <: Record[BaseRecord]] {
  self: BaseRecord =>
...
  def fieldByName(fieldName: String, inst: BaseRecord): Box[Field[_, BaseRecord]] = {
    Box(fieldMap.get(fieldName).map(_.field(inst)))
...
  }
trait OwnedField[OwnerType <: Record[OwnerType]] extends BaseField {
...
}
trait BaseField extends FieldIdentifier with util.BaseField {
...
}
trait TypedField[ThisType] extends BaseField {
...
}
trait Field[ThisType, OwnerType <: Record[OwnerType]] extends OwnedField[OwnerType] with TypedField[ThisType] {
...
}

class RecordMetaDataFactory extends FieldMetaDataFactory {
...
  private var metaRecordsByClass: Map[Class[_], MetaRecord[_]] = Map.empty
...
  private def findMetaField(clasz: Class[_], name: String): BaseField = {
    def fieldFrom(mr: MetaRecord[_]): BaseField =
      mr.asInstanceOf[Record[_]].fieldByName(name) match {
        case Full(f: BaseField) => f
        case Full(_) => org.squeryl.internals.Utils.throwError("field " + name + " in Record metadata for " + clasz + " is not a TypedField")
        case _ => org.squeryl.internals.Utils.throwError("failed to find field " + name + " in Record metadata for " + clasz)
      }

    metaRecordsByClass get clasz match {
      case Some(mr) => fieldFrom(mr)
      case None =>
        try {
          val rec = clasz.newInstance.asInstanceOf[Record[_]]
          val mr = rec.meta
          metaRecordsByClass = metaRecordsByClass updated (clasz, mr)
          fieldFrom(mr)
        } catch {
          case ex => org.squeryl.internals.Utils.throwError("failed to find MetaRecord for " + clasz + " due to exception " + ex.toString)
        }
    }
  }

}

At this point I get errors inside findMetaField such as:
[error] /home/naftoli/dev/liftweb/framework/persistence/squeryl-record/src/main/scala/net/liftweb/squerylrecord/RecordMetaDataFactory.scala:39: type arguments [?,_$5] do not conform to trait Field's type parameter bounds [ThisType,OwnerType <: net.liftweb.record.Record[OwnerType]]
[error]         case Full(f: BaseField) => f
[error]                  ^
[error] /home/naftoli/dev/liftweb/framework/persistence/squeryl-record/src/main/scala/net/liftweb/squerylrecord/RecordMetaDataFactory.scala:38: type arguments [?,_$5] do not conform to trait Field's type parameter bounds [ThisType,OwnerType <: net.liftweb.record.Record[OwnerType]]
[error]       mr.asInstanceOf[Record[_]].fieldByName(name) match {
[error]                                             ^

I tried a lot of massaging and only managed to exchange the errors for some others. For instance using T forSome { type T <: Record[T] } didn't seem to work.

Any ideas?

Aleksey Nikiforov

unread,
Nov 22, 2012, 10:52:40 AM11/22/12
to scala-l...@googlegroups.com
From a quick glance it looks like the problem is creating a concrete type from a recursive type. If that is the case, then try the following hack. It is not pretty, but it should get the job done:

val Recursor: { type Recursive <: Record[Recursive] } = null
type Recursive = Recursor.Recursive

Having to rely on these hacks led me to abandon recursive types in the first place. Please let me know if you find a more elegant solution.

Chris Marshall

unread,
Nov 22, 2012, 12:11:01 PM11/22/12
to scala-l...@googlegroups.com
You can also use existentials:

MyType[T] forSome { type T <: MyType[T] }

Chris

nafg

unread,
Nov 23, 2012, 4:48:43 AM11/23/12
to scala-l...@googlegroups.com
Thanks, that worked!
It's not my code here, but in general how do you encode MyType without them? Abstract type members cannot be used in the self type, I don't think.
 
Reply all
Reply to author
Forward
0 new messages