2017-01-04 2 views
1

У меня есть следующий код, использующий ReaderWriterState от Scalaz. Мой общий параметр типа K выводится как «Nothing» во время компиляции. Может кто-нибудь, пожалуйста, скажите мне, что происходит?scala generic type doess to 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) на линии

Рез < - processEventSet (е) из 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

Функция

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]] 

Это может дать компилятору достаточную информацию для вывода типа. (Хотя я его не тестировал.)

+0

Благодарим за ответ. Я попробовал, и это не решает проблему. В соответствии с вашим ответом, я могу представить, если f является f: K => R, если он удовлетворяет компилятору? (В моем случае это не применяется). – huoenter

+0

Для того, чтобы компилятор мог выводить типы, ему нужна определенная подсказка. Если тип появляется в аргументах, компилятор знает тип аргумента и может выводить неизвестные параметры типа. Затем они используются для вычисления результирующего типа. 'K' в вашем случае отсутствует в аргументах. Поэтому компилятор не может это сделать. Как компилятор может догадаться, что означает 'K'? –