我在相应的伴随对象中有一些unapply
的案例类,我将其用于模式匹配,如下所示:
trait DAO [T] {
def create: Int
def insert(model: List[T]): Int
def update(id: String, name: String): Int
def delete(id: String): Int
def all: List[T]
def find(id: String): List[T]
def findSome(id: String): List[T]
}
sealed trait Service[A]
final case class Create[A](implicit val dao: DAO[A]) extends Service[Int]
final case class Insert[A](model: List[A], implicit val dao: DAO[A]) extends Service[Int]
object Create_{
def unapply[A](in: Create [A])= Some(in.dao)
}
object Insert_ {
def unapply[A](in: Insert[A]) = Some((in.model,in.dao))
}
case class F(id:String)
implicit val abc = new DAO[F] {
def create = 1
def insert(model: List[F]) = 1
def update(id: String, name: String) = 1
def delete(id: String) = c1
def all = List(F("Test"))
def find(id: String) = List(F("Test"))
def findSome(id: String) = List(F("Test"))
}
def b[A](in: Service[A]) = {
in match {
case Create_(dao) => dao.create
case Insert_(model, dao) => dao.insert(model)
}
}
当我加载上述文件时,REPL会抱怨以下错误:
scala> :load ..../tools/scala/macros/test.scala
Loading ...../tools/scala/macros/test.scala...
defined trait DAO
defined trait Service
defined class Create
defined class Insert
defined class F
defined object Create_
defined object Insert_
abc: DAO[F] = $anon$1@3e776a48
<console>:65: error: type mismatch;
found : List[Any]
required: List[A] where type +A
case Insert_(model, dao) => dao.insert(model)
它没有编译。
答案 0 :(得分:1)
问题在于:
Insert[+A,B](model: List[A], implicit val dao:DAO[B])
您允许模型和DAO的列表元素使用不同的类型,但DAO只需要一种类型:
def insert(model:List[T]):Int
您可以通过要求插入类型相同来解决此问题。然后保证您为DAO传递正确的模型类型。
Insert[A](model: List[A], implicit val dao:DAO[A])
答案 1 :(得分:1)
剩下的问题是case class Create[A](implicit val dao: DAO[A])
与case class Create[A]()(implicit val dao: DAO[A])
相同。因此case Create(dao)
是非法的,而是case Create()
。使用case Create_(dao)
或从implicit val
类定义中删除Create
。
答案 2 :(得分:0)
解决方案是
def b[A](in: Service[A]) = {
in match {
case Create_(dao) => dao.create
case Insert_(model:List[A], dao:DAO[A]) => dao.insert(model)
}
还有警告!!!
scala> :load .../tools/scala/macros/Test.scala
Loading .../tools/scala/macros/Test.scala...
defined trait DAO
import scalaz.{Free, $tilde$greater, Id, Coyoneda}
defined trait Service
defined trait Command
defined type alias Functor
defined class Create
defined class Insert
defined class Execute
defined class F
defined object Create_
defined object Insert_
defined object Execute_
lift: [A](service: Service[A])scalaz.Free[Functor,A]
abc: DAO[F] = $anon$1@2a071108
<console>:219: warning: abstract type pattern A is unchecked since it is eliminated by erasure
case Insert_(model:List[A], dao:DAO[A]) => dao.insert(model)
^
<console>:219: warning: abstract type A in type pattern DAO[A] is unchecked since it is eliminated by erasure
case Insert_(model:List[A], dao:DAO[A]) => dao.insert(model)
^
<console>:217: warning: match may not be exhaustive.
It would fail on the following input: Insert(_, _)
in match {
^
b: [A](in: Service[A])Int