Scala 如何进行一元递归?

Scala 如何进行一元递归?,scala,recursion,scala-cats,Scala,Recursion,Scala Cats,我尝试按如下方式进行一元递归: object KkConsumer { private val delegate = Executors.defaultThreadFactory() def create (consumer: KkConsumerCreator): IO[Consumer[String, String]] = IO { val c = new KafkaConsumer[String, String](properties(consumer)

我尝试按如下方式进行一元递归:

object KkConsumer {

  private val delegate = Executors.defaultThreadFactory()

  def create
  (consumer: KkConsumerCreator): IO[Consumer[String, String]] =
    IO {
      val c = new KafkaConsumer[String, String](properties(consumer))
      c.subscribe(consumer.topic.asJavaCollection)
      c
    }

  def build[A]
  (consumer: Consumer[String, String])(cb: Vector[KkConsumerRecord] => IO[A])
  : IO[Thread] =
    for {
      t <- IO {
        val thread = delegate.newThread(() => {
          pool(consumer)(cb)
        })
        thread.setDaemon(true)
        thread
      }
    } yield t

  def run(thread: Thread): IO[Thread] =
    IO {
      thread.run()
      thread
    }

  //@tailrec
  private def pool[A]
  (consumer: Consumer[String, String])(cb: Vector[KkConsumerRecord] => IO[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).flatMap(_ => pool(consumer)(cb))
  }

  private def properties
  (consumer: KkConsumerCreator): Properties =
    Foldable[List]
      .foldRight(consumer.props, Later(new Properties())) { (a, b) =>
        a match {
          case ClientId(value) => b.map { p =>
            p.put(ConsumerConfig.CLIENT_ID_CONFIG, value)
            p
          }

          case AutoOffsetResetConfig(value) => b.map { p =>
            p.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, value)
            p
          }
        }
      }.map { p =>
      p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, consumer.host)
      p.put(ConsumerConfig.GROUP_ID_CONFIG, consumer.groupId)
      p.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer")
      p.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer")
      p
    }.value

}
这就是我对一元递归的意思。
我使用的方法如下:

  def main(args: Array[String]) {

    sys.addShutdownHook {
      latch.countDown
      println("exiting")
    }

    try {

      val c = KkConsumerCreator("localhost:9092", "khinkali", List("TEST"), List(ClientId("KHINKALI-IO"), AutoOffsetResetConfig("latest")))

      (for {
        c <- KkConsumer.create(c)
        b <- KkConsumer.build(c)(observe)
        t <- KkConsumer.run(b)
      } yield t).unsafeRunSync()

      latch.await
    } catch {
      case e: Throwable =>
        System.exit(1)
    }

    System.exit(0)


  }

  def observe(rec: Vector[KkConsumerRecord]): IO[Unit] =
    IO {
      println("Hello")
      println("Hell2")
    }

}
def main(参数:数组[字符串]){ sys.addShutdownHook{ 倒数计时 println(“退出”) } 试一试{ val c=KkConsumerCreator(“本地主机:9092”、“khinkali”、列表(“测试”)、列表(ClientId(“khinkali-IO”)、自动偏移设置(“最新”)) (用于{
正如您所说,在
build
中将回调传递到
中的
后,回调永远不会调用
.unsafe*
。因为您自己管理线程,所以在这个程序中,将
池(消费者)(cb)
替换为
池(消费者)(cb)。unsafeRunSync()
  def main(args: Array[String]) {

    sys.addShutdownHook {
      latch.countDown
      println("exiting")
    }

    try {

      val c = KkConsumerCreator("localhost:9092", "khinkali", List("TEST"), List(ClientId("KHINKALI-IO"), AutoOffsetResetConfig("latest")))

      (for {
        c <- KkConsumer.create(c)
        b <- KkConsumer.build(c)(observe)
        t <- KkConsumer.run(b)
      } yield t).unsafeRunSync()

      latch.await
    } catch {
      case e: Throwable =>
        System.exit(1)
    }

    System.exit(0)


  }

  def observe(rec: Vector[KkConsumerRecord]): IO[Unit] =
    IO {
      println("Hello")
      println("Hell2")
    }

}