scala泛型类型推断为零

时间:2017-01-04 20:18:29

标签: scala scalaz

我使用Scalaz的ReaderWriterState获得以下代码。我的泛型类型参数K在编译期间被推断为Nothing。有人可以告诉我发生了什么事吗?

object O {
    type VM = VirtualMachine

    def getQueue[K, R]: RWS[VM, Map[K, R], EventQueue, Unit] = RWS {
        case (vm, s) => (Map[K,R](), (), s)
    }

    def processEventSet[K, R](f: Event => R): RWS[VM, Map[K,R], EventQueue, Seq[R]] = RWS {
        case (vm, q) => 
            val set = q.remove
            (Map.empty[K, R], set.eventIterator.toSeq map f, q)
    }

    def resume[K, R]: RWS[VM, Map[K,R], EventQueue, Seq[R]] = RWS {
        case (vm, q) => vm.resume();(Map.empty[K,R], List.empty[R], q)
    }

    def process(f: Event => Int): RWS[VM, Map[Int, Int], EventQueue, Seq[Int]] = for {
        _ <- getQueue
        res <- processEventSet(f)
        _ <- resume
    } yield res

    def processT[K, R](f: Event => R): RWS[VM, Map[K,R], EventQueue, Seq[R]] = for {
        _ <- getQueue
        res <- processEventSet(f)
        _ <- resume
    } yield res
}

行上的错误(sbt 11.3,scalaz 7.3)

res&lt; - processEventSet(f) of processT

**found   : Seq[R] => scalaz.IndexedReaderWriterStateT[scalaz.Id.Id,O.VM,Map[Nothing,R],com.sun.jdi.event.EventQueue,com.sun.jdi.event.EventQueue,Seq[R]]
[error]     (which expands to)  Seq[R] => scalaz.IndexedReaderWriterStateT[scalaz.Id.Id,com.sun.jdi.VirtualMachine,Map[Nothing,R],com.sun.jdi.event.EventQueue,com.sun.jdi.event.EventQueue,Seq[R]]
[error]  required: Seq[R] => scalaz.IndexedReaderWriterStateT[scalaz.Id.Id,O.VM,Map[K,R],com.sun.jdi.event.EventQueue,com.sun.jdi.event.EventQueue,Seq[R]]
[error]     (which expands to)  Seq[R] => scalaz.IndexedReaderWriterStateT[scalaz.Id.Id,com.sun.jdi.VirtualMachine,Map[K,R],com.sun.jdi.event.EventQueue,com.sun.jdi.event.EventQueue,Seq[R]]
[error]                 res <- processEventSet(f)
[error]                     ^
[error] XXX:218: diverging implicit expansion for type scalaz.Semigroup[Map[K,R]]
[error] starting with value intInstance in trait AnyValInstances
[error]                 _ <- getQueue
[error]                   ^**

1 个答案:

答案 0 :(得分:1)

功能

def processEventSet[K, R](f: Event => R): RWS[VM, Map[K,R], EventQueue, Seq[R]] 

没有任何关于如何推断类型K的线索。所有类型都应该来自函数参数。

您可能希望显式提供它,或者创建另一个允许编译器推断类型的参数(甚至是隐式的)。例如:

trait TypeHelper[K,R]
implicit object intHelper extends TypeHelper[Int, Int] 

def processEventSet[K, R](f: Event => R)(implicit ev: TypeHelper[K,R]): 
  RWS[VM, Map[K,R], EventQueue, Seq[R]] 

这可能会为编译器提供足够的信息来推断类型。 (虽然我还没有测试过它。)