标签: scala-cats

如何解释 Fold 和 FoldK 之间的区别?

在一名程序员刚刚学习函数式编程并完成在线 Scala 猫练习的背景,以下结果似乎令人费解:

import cats._
import cats.implicits._

object Foo {

  def main(args: Array[String]): Unit =
    println(Foldable[List].fold(List(None, Option("two"), Option("three"))))
    //Some("twothree")
    println(Foldable[List].foldK(List(None, Option("two"), Option("three"))))
    //Some("two")
}
Run Code Online (Sandbox Code Playgroud)

我可以遵循 for 的示例fold,但不能遵循 for 的示例foldKFoldK 的文档说:

此方法与 Fold 相同,只是我们使用通用幺半群 ( MonoidK[G]) 来获取Monoid[G[A]]实例。

我不明白这种差异如何导致上面看到的行为,其中列表中的第三个元素 ( Option("three")) 被“忽略” foldK

有人可以解释一下吗?

scala scala-cats

4
推荐指数
1
解决办法
686
查看次数

如何在没有 ExecutionContext.global 和 IOApp 的情况下使用 cat 效果中的计时器?

我有一个简单的 IO 操作序列,暂停 5 秒。

  implicit val timer = IO.timer(ExecutionContext.global)

  def doSth(str: String): IO[Unit] = IO(println(str))
  def greeting(): IO[Unit] =
    doSth("Before timer.") *>
      Timer[IO].sleep(5 second) *>
      doSth("After timer")

  val a = greeting().unsafeRunAsyncAndForget()
Run Code Online (Sandbox Code Playgroud)

如何使计时器没有ExecutionContext.globalIOApp或固定线程数量ExecutionContext.global

scala spring-data-jpa scala-cats

4
推荐指数
1
解决办法
922
查看次数

如何堆叠 State 和 IO monad

在 Connect4 游戏中:

  • 我们从一个空的网格开始
  • 两名玩家将 x 和 o 放在网格上
  • 第一个达到 4 个棋子的玩家获胜!
  • 这是一个基于文本的控制台游戏

我的想法是:

  • 在游戏的每一步,网格都从一种状态过渡到另一种状态
  • 因此我需要使用 State monad
  • 并且因为这是一个基于控制台的应用程序,涉及 io
  • 在这种情况下,我还需要使用 IO monad

这种想法正确吗?

假设以上是正确的,以下哪一项是正确的?

  • 类型 StateInIO[S,A] = IO[State[S,A]]
  • 类型 IOInState[S,A] = 状态 [S,IO[A]]

我赞成第二种选择,对我来说更有意义。

我可以用这种方式堆叠这些 monads (State, IO) 吗?

monads functional-programming scala scala-cats

4
推荐指数
1
解决办法
281
查看次数

Scala Cat 使用 Ior 累积错误和成功

我正在尝试使用 Cats 数据类型 Ior 来累积使用服务的错误和成功(可能返回错误)。

def find(key: String): F[Ior[NonEmptyList[Error], A]] = {
  (for {
      b <- service.findByKey(key)
    } yield b.rightIor[NonEmptyList[Error]])
  .recover {
      case e: Error => Ior.leftNel(AnotherError)
    }
}

def findMultiple(keys: List[String]): F[Ior[NonEmptyList[Error], List[A]]] = {
  keys map find reduce (_ |+| _)
}
Run Code Online (Sandbox Code Playgroud)

我的困惑在于如何组合错误/成功。我正在尝试使用 Semigroup combine(中缀语法)进行组合,但没有成功。有一个更好的方法吗?任何帮助都会很棒。

scala scala-cats

4
推荐指数
1
解决办法
386
查看次数

如何使用 Monoid Scala?

trait Monoid[A] {
  def op(a1: A, a2: A): A

  def zero: A
}

def mapMergeMonoid[K, V](V: Monoid[V]): Monoid[Map[K, V]] = new Monoid[Map[K, V]] {
    override def op(a1: Map[K, V], a2: Map[K, V]): Map[K, V] =
      (a1.keySet ++ a2.keySet).foldLeft(zero) {
        (acc, k) => acc.updated(k, V.op(a1.getOrElse(k, V.zero), a2.getOrElse(k, V.zero)))
      }

    override def zero: Map[K, V] = Map[K, V]()
  }
Run Code Online (Sandbox Code Playgroud)

据我所知,我可以用这个 Monoid 连接 2 个 Map。但我无法理解,如何使用它。我必须放入(V: Monoid[V])参数以使用op方法之后并放置2张地图。

functional-programming scala scalaz monoids scala-cats

4
推荐指数
1
解决办法
678
查看次数

Scala、ZIO - 将 Future 转换为 ZIO 或将 ZIO 转换为 Future。是否可以?

我创建了两个版本的服务。第一个使用Futures,另一个使用ZIO效果。

我有一个简单的方法,使用Future结果效果:

def get(id: String)(implicit executionContext: ExecutionContext): Future[Data]
Run Code Online (Sandbox Code Playgroud)

我还有一些其他版本使用ZIO[SomeEnv, SomeError, Data]

def get(id: String): ZIO[SomeEnv, SomeError, Data]
Run Code Online (Sandbox Code Playgroud)

现在,我需要创建某种适配器,它将从一个版本或另一个版本返回数据:

def returnDataFromServiceVersion(version: Int) : ??? = {
   if(version == 1) futureService.get(...)
   else zioService.get(...)
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是返回类型。我不知道如何转换ZIO为未来或Future转换ZIO为具有共同的返回类型。我尝试使用ZIO.fromFuture{...}ortoFuture()但没有帮助。我的问题是 - 如何创建此returnDataFromServiceVersion方法以将其与这两种服务一起使用?我需要在这里有共同的返回类型。

或者也许有另一种方法可以解决这个问题?

scala future scala-cats zio

4
推荐指数
1
解决办法
2593
查看次数

跳过无限流中的错误

我有一个fs2.Stream可能会遇到错误的无限。我想跳过这些错误而不做任何事情(可能是日志)并继续流式传输更多元素。例子:

//An example
val stream = fs2.Stream
    .awakeEvery[IO](1.second)
    .evalMap(_ => IO.raiseError(new RuntimeException))
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,我想获得无限fs2.StreamLeft(new RuntimeException)发射每一秒。

有一种Stream.attempt方法可以生成在遇到第一个错误后终止的流。有没有办法跳过错误并继续拉取更多元素?

IO.raiseError(new RuntimeException).attempt通常不会起作用,因为它需要在流管道组合的所有位置尝试所有效果。

functional-programming scala scala-cats fs2

4
推荐指数
1
解决办法
457
查看次数

为什么导入类型类实例不再需要 import cats.implicits._ ?

在 Cats 2.1.x 中,类型类实例被引入范围内import cats.implicits._

scala> import cats.Show
import cats.Show

scala> Show[Int].show(42)
<console>:13: error: could not find implicit value for parameter instance: cats.Show[Int]
       Show[Int].show(42)
           ^

scala> import cats.implicits._
import cats.implicits._

scala> Show[Int].show(42)
res1: String = 42
Run Code Online (Sandbox Code Playgroud)

然而在 Cats 2.2.0中,它无需import cats.implicits._例如

scala> import cats.Show
import cats.Show

scala> Show[Int].show(42)
val res0: String = 42
Run Code Online (Sandbox Code Playgroud)

发生了什么变化以及从现在开始我们应该如何使用导入?

import scala implicit typeclass scala-cats

4
推荐指数
1
解决办法
1543
查看次数

如何异步中断 fs2 流?

我正在尝试使用 SignalRef 中断 fs2 流。我使用以下命令设置并运行流。流应在switch包含时运行,并在包含false时中断switchtrue

  import cats.effect.IO
  import fs2.Stream
  import fs2.concurrent.SignallingRef

  import scala.concurrent.ExecutionContext
  import scala.concurrent.duration.DurationInt

  implicit val contextShift = IO.contextShift(ExecutionContext.global)
  implicit val timer = IO.timer(ExecutionContext.global)

  val switch: IO[SignallingRef[IO, Boolean]] = SignallingRef[IO, Boolean](false)

  val program: Stream[IO, Unit] = {

      val program: Stream[IO, Unit] =
        Stream
          .repeatEval(IO{
            println(java.time.LocalTime.now)
            println(switch.map(_.get).unsafeRunSync.unsafeRunSync)
          })
          .metered(1.second)

      program
        .interruptWhen(Stream.repeatEval(switch.map(_.get).unsafeRunSync))
    }
  
  program.compile.drain.unsafeRunAsync(() => _)
Run Code Online (Sandbox Code Playgroud)

然后我尝试中断流

switch.map(_.set(true).unsafeRunSync)
Run Code Online (Sandbox Code Playgroud)

然而,这股潮流仍在继续。在标准输出中我看到

15:58:33.048504
false
15:58:34.048760
false
15:58:35.049063
false
15:58:36.049356
false
15:58:37.049615
false
Run Code Online (Sandbox Code Playgroud)

那么显然它没有切换到 true 吗?

scala scala-cats fs2 cats-effect

4
推荐指数
1
解决办法
2073
查看次数

猫:如何从implicits中找到特定类型

我有这个代码编译和工作正常

import cats.implicits._
Cartesian[ValidResponse].product(
    getName(map).toValidated,
    readAge(map).toValidated
).map(User.tupled)
Run Code Online (Sandbox Code Playgroud)

但是我不喜欢导入,cats.implicits._因为那里的课程太多了.我尝试导入与笛卡尔相关的特定事物

import cats.implicits.catsSyntaxCartesian
import cats.implicits.catsSyntaxUCartesian
import cats.implicits.catsSyntaxTuple2Cartesian
Run Code Online (Sandbox Code Playgroud)

但这些都行不通.作为一个新手,我发现隐式导入非常令人困惑,因为它们只有1000个并且名称不是很明显.我唯一的选择是导入整个宇宙import cats.implicits._并停止思考它.

其实我有更广阔的混乱cats.implicits,cats.instances._cats.syntax._.到目前为止,我只是通过反复试验导入这些.我不确定何时导入什么.

scala scala-cats

3
推荐指数
1
解决办法
362
查看次数