--- a/src/main/scala/rdf/ConcreteRDFModel.scala Sun Nov 20 23:21:56 2011 -0500
+++ b/src/main/scala/rdf/ConcreteRDFModel.scala Mon Nov 21 11:58:10 2011 -0500
@@ -38,11 +38,14 @@
object PredicateIRI extends Isomorphic1[IRI, PredicateIRI]
sealed trait Object {
- def unapply(o: Object): Option[Object] = o match {
- case on: ObjectNode => Some(on)
- case ol: ObjectLiteral => Some(ol)
- case _ => None
- }
+// def unapply(o: Object): Option[Object] = {
+// println("*** do I get here?")
+// o match {
+// case on: ObjectNode => Some(on)
+// case ol: ObjectLiteral => Some(ol)
+// case _ => None
+// }
+// }
}
case class ObjectNode(n: Node) extends Object
object ObjectNode extends Isomorphic1[Node, ObjectNode]
--- a/src/main/scala/rdf/main.scala Sun Nov 20 23:21:56 2011 -0500
+++ b/src/main/scala/rdf/main.scala Mon Nov 21 11:58:10 2011 -0500
@@ -3,11 +3,74 @@
import java.io.File
import com.hp.hpl.jena.graph.Graph
+// afaik, the compiler doesn't not expose the unapply method
+// for a companion object
+trait Isomorphic[A, B] {
+ def apply(x: A): B
+ def unapply(x: B): Option[A]
+}
+
+// abstract module
+trait Module {
+ // 3 types with some contraints
+ type X
+ type Y <: X
+ type Z <: X
+ // and their "companion" objects
+ def X: Isomorphic[Int, X]
+ def Y: Isomorphic[X, Y]
+ def Z: Isomorphic[Y, Z]
+}
+
+// an implementation relying on case classes
+object ConcreteModule extends Module {
+ sealed trait X { val i: Int = 42 }
+ object X extends Isomorphic[Int, X] {
+ def apply(_s: Int): X = new X { }
+ def unapply(x: X): Option[Int] = Some(x.i)
+ }
+ case class Y(x: X) extends X
+ // I guess the compiler could do that for me
+ object Y extends Isomorphic[X, Y]
+ case class Z(y: Y) extends X
+ object Z extends Isomorphic[Y, Z]
+}
+
+object Main2 {
+ def foo(t: Module)(x: t.X): Unit = {
+ import t._
+ // the output depends on the order of the first 3 lines
+ // I'm not sure what's happening here...
+ x match {
+ // unchecked since it is eliminated by erasure
+ case Y(_y) => println("y "+_y)
+ // unchecked since it is eliminated by erasure
+ case Z(_z) => println("z "+_z)
+ // this one is fine
+ case X(_x) => println("x "+_x)
+ case xyz => println("xyz "+xyz)
+ }
+ }
+ def bar(t: Module): Unit = {
+ import t._
+ val x: X = X(42)
+ val y: Y = Y(x)
+ val z: Z = Z(y)
+ foo(t)(x)
+ foo(t)(y)
+ foo(t)(z)
+ }
+ def main(args: Array[String]) = {
+ // call bar with the concrete module
+ bar(ConcreteModule)
+ }
+}
object Main {
def main(args: Array[String]) = {
+//
// val turtle = new org.w3.rdf.turtle.TurtleParser(org.w3.rdf.jena.JenaModel)
//
// val g = turtle.toGraph(new File("/tmp/card.n3"))
--- a/src/main/scala/rdf/turtle.scala Sun Nov 20 23:21:56 2011 -0500
+++ b/src/main/scala/rdf/turtle.scala Mon Nov 21 11:58:10 2011 -0500
@@ -99,13 +99,21 @@
// as the Module type does not escape from any method here, we can pass it at the constructor level
class TurtleSerializer {
- //val rdf = ConcreteRDFModel
+ //type RDFModel = ConcreteRDFModel
+ class Def[C](implicit desired : Manifest[C]) {
+ def unapply[X](c : X)(implicit m : Manifest[X]) : Option[C] = {
+ def sameArgs = desired.typeArguments.zip(m.typeArguments).forall {case (desired,actual) => desired >:> actual}
+ if (desired >:> m && sameArgs) Some(c.asInstanceOf[C])
+ else None
+ }
+ }
def showAsString(rdf: RDFModel)(g: rdf.Graph): String = {
g map {
t =>
- val rdf.Triple(rdf.SubjectNode(s), rdf.PredicateIRI(p), o) = t
+ //val rdf.Triple(rdf.SubjectNode(s), rdf.PredicateIRI(p), o: rdf.Object) = t
+ val rdf.Triple(rdf.SubjectNode(s), rdf.PredicateIRI(p), o: rdf.Object) = t
try {
"%s %s %s" format (nodeStr(rdf)(s), iriStr(rdf)(p), objectStr(rdf)(o))
} catch {
@@ -122,12 +130,11 @@
def objectStr(rdf: RDFModel)(n: rdf.Object): String = {
n match {
-// case l:rdf.ObjectLiteral => {
-// val x:rdf.ObjectLiteral = l
-// "**ObjectLiteral(" + x + ")**"
-// }
- case rdf.ObjectNode(n) => nodeStr(rdf)(n)
+ case rdf.ObjectNode(on) => nodeStr(rdf)(on)
case rdf.ObjectLiteral(l) => literalStr(rdf)(l)
+// case on: rdf.ObjectNode => { val rdf.ObjectNode(oo) = on; nodeStr(rdf)(oo) }
+// case l: rdf.ObjectLiteral => { val rdf.ObjectLiteral(ll) = l; literalStr(rdf)(ll) }
+
case x => { sys.error(x.toString) }
}
}