当前位置:  开发笔记 > 编程语言 > 正文

类型不匹配cats.Monad [?]?

如何解决《类型不匹配cats.Monad[?]?》经验,为你挑选了1个好方法。

我有以下函数,它做递归:

  @tailrec
  private def pool[F[_]: Monad, A]
  : Consumer[String, String] => (Vector[KkConsumerRecord] => F[A]) => IO[Unit]
  = consumer => cb => {
    val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue)
    val converted = records.iterator().asScala.map(rec => {
      KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic())
    })

    val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) =>
      a +: b
    }
    cb(vec)
    pool(consumer)(cb)
  }

编译器抱怨:

[error] /home/developer/Desktop/microservices/bary/kafka-api/src/main/scala/io/khinkali/Consumer/KkConsumer.scala:57:10: type mismatch;
[error]  found   : org.apache.kafka.clients.consumer.Consumer[String,String]
[error]  required: cats.Monad[?]
[error]     pool(consumer)(cb)
[error]          ^
[error] two errors found

我究竟做错了什么?



1> Dmytro Mitin..:

以下代码编译:

import cats.Monad
import cats.effect.IO
import org.apache.kafka.clients.consumer.{Consumer, ConsumerRecords}
import scala.collection.JavaConverters._
import scala.annotation.tailrec

object App {
  case class KkConsumerRecord(key: String, value: String, offset: Long, partition: Int, topic: String)

//  @tailrec
  private def pool[F[_]: Monad, A]
  : Consumer[String, String] => (Vector[KkConsumerRecord] => F[A]) => IO[Unit]
  = consumer => cb => {
    val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue)
    val converted = records.iterator().asScala.map(rec => {
      KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic())
    })

    val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) =>
      a +: b
    }
    cb(vec)
    pool.apply(consumer)(cb)
  }
}

def pool[F[_]: Monad, A]意味着def pool[F[_], A](implicit monad: Monad[F])编译器被误consumer认为是隐式参数.

tailrec注释被删除,因为pool不是尾递归(最后一个操作是构造lambda,我猜它叫做尾递归模数).


如果你想使它尾递归,你可以将其重写为

  @tailrec
  private def pool[F[_]: Monad, A](consumer: Consumer[String, String])(cb: Vector[KkConsumerRecord] => F[A]): IO[Unit] = {
    val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue)
    val converted = records.iterator().asScala.map(rec => {
      KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic())
    })

    val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) =>
      a +: b
    }
    cb(vec)
    pool(consumer)(cb)
  }

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有