我正在尝试编写工厂来创建案例类。我正在创建一个命令行工具,它接受案例类参数的字符串表示。无论如何,想法是限制为新类型创建隐式的添加更改,但我似乎无法超越起始线。下面是一些试图创建一个case对象的代码(所以没有参数 - 最简单的情况),但是scalac抱怨它"找不到参数factory"的隐含值。一定是stoopid的东西,但我已经尝试了我能想到的一切。如果有人能指出我正确的方向,那将是非常感激的。感谢。
object Message {
case object Person
sealed trait Repr[T] {
def value: T
}
trait Parm0Factory[R] {
def instance(): R
}
implicit val personFactory = new Parm0Factory[Person.type] {
def instance() = Person
}
case class Parm0[R]() extends Repr[R] {
override def value(): R = xform
private def xform(implicit factory: Parm0Factory[R]): R = factory.instance()
}
def main(args: Array[String]): Unit = {
val t1 = Parm0[Person.type]()
println(t1.value)
}
}
答案 0 :(得分:3)
您有vector<Mat> RImages;
vector<Mat> hImages;
RImages.reserve(blocks_width * blocks_height);
hImages.reserve(blocks_width * blocks_height);
for ( int idx = 0; idx < blocks_width * blocks_height; idx++ )
{
...
Mat temp;
RImages.emplace_back(imread( filename , 1 ) );
cvtColor( RImages[ idx ], temp , CV_BGR2HSV );
hImages.emplace_back(temp );
}
的隐式定义,但您的PersonFactory[Person.Type]
来电正在寻找而未找到的是xform
。它的类型不同。
答案 1 :(得分:0)
我做了一些研究,并且能够提出我的想法的实现,现在非常令人满意(至少对我来说)。简而言之,我想维护一个用户可以就地修改的递归树结构的String表示,然后能够将该表示转换为实际的实例。结果类型类是我正在寻找的。以为我会继续发布这个,因为那里的人至少不像我那样熟悉使用类型类。 如果有人知道如何删除必须提供类型参数来调用'build',请告诉我。此外,我希望有一个更清晰的隐式构建器函数实现,它不使用'@unchecked'注释来消除烦人的编译器警告。 : - )
object Messages {
// Test classes
case class Person(name: String, age: Int, pet: Dog)
case class Dog(name: String)
case class Device(deviceType: DeviceType, on: Boolean)
sealed trait DeviceType
case class Android() extends DeviceType
case class iOS() extends DeviceType
case class Windows() extends DeviceType
// Builders...
trait Builder[A] {
def build: Node => A
}
object Builder {
def build[A](f: Node => A) = new Builder[A] {
val build = f
}
// Terminals...
implicit val intBuilder: Builder[Int] = build(node => (node: @unchecked) match {
case Term(_, value) => value.toInt
})
implicit val stringBuilder: Builder[String] = build(node => (node: @unchecked) match {
case Term(_, value) => value
})
implicit val booleanBuilder: Builder[Boolean] = build(node => (node: @unchecked) match {
case Term(_, value) => value.toBoolean
})
// Case classes (composites)
implicit val dogBuilder: Builder[Dog] = build[Dog](node => (node: @unchecked) match {
case Tree(_, children) =>
Dog(children(0).build[String])
})
implicit val personBuilder: Builder[Person] = build[Person](node => (node: @unchecked) match {
case Tree(_, children) =>
Person(children(0).build[String], children(1).build[Int], children(2).build[Dog])
})
implicit val deviceTypeBuilder: Builder[DeviceType] = build[DeviceType](node => (node: @unchecked) match {
case Term(_, value) => value match {
case "Android" => Android()
case "iOS" => iOS()
case "Windows" => Windows()
}
})
implicit val deviceBuilder: Builder[Device] = build[Device] (node => (node: @unchecked) match {
case Tree(_, children) => Device(children(0).build[DeviceType], children(1).build[Boolean])
})
}
// Data Structures...
sealed trait Node {
val name: String
def prompt: String
def build[A: Builder]: A = implicitly[Builder[A]].build(this)
}
case class Tree(name: String, children: IndexedSeq[Node]) extends Node {
override def prompt = {
val choices = children.zipWithIndex.map { case (node, idx) => s"${idx + 1}) ${node.name}" }.mkString("\n")
s"$toString\n$choices\n"
}
override def toString = name + children.mkString("(", ", ", ")")
}
case class Term(name: String, value: String) extends Node {
override def prompt = s"$name = "
override def toString = s"$name = $value"
}
def main(args: Array[String]): Unit = {
val person = Tree("Person", IndexedSeq[Node](Term("name", "Fred"), Term("age", "45"),
Tree("pet", IndexedSeq[Node](Term("name", "Fido")))))
val device = Tree("some device", IndexedSeq[Node](Term("type", "iOS"), Term("on", "true")))
println(person.prompt)
println(person.toString)
// TODO How to remove necessity of providing type parameter?
println(person.build[Person])
println(device.build[Device])
}
}