标签: scala-cats

如何在 Scala Cats Effect 中的 List[IO[Boolean]] 中遇到第一个“true”时返回

假设我有一组规则,其中有一个IO[Boolean]在运行时返回的验证函数。

case class Rule1() {
  def validate(): IO[Boolean] = IO.pure(false)
}
case class Rule2() {
  def validate(): IO[Boolean] = IO.pure(false)
}
case class Rule3() {
  def validate(): IO[Boolean] = IO.pure(true)
}

val rules = List(Rule1(), Rule2(), Rule3())
Run Code Online (Sandbox Code Playgroud)

现在我必须迭代这些规则并查看“这些规则中的任何一个是否有效”,如果不有效则抛出异常!

for {
  i <- rules.map(_.validate()).sequence
  _ <- if (i.contains(true)) IO.unit else IO.raiseError(new RuntimeException("Failed"))
} yield ()
Run Code Online (Sandbox Code Playgroud)

上面代码片段的问题在于它试图评估所有规则!我真正想要的是在第一次验证时退出true

不知道如何在 Scala 中使用猫效果来实现这一点。

scala exists findfirst scala-cats cats-effect

5
推荐指数
2
解决办法
413
查看次数

猫Seq [Xor [A,B]] => Xor [A,Seq [B]]

我有一系列的错误或观点(Seq[Xor[Error,View]])

我想将此映射到第一个错误的Xor(如果有)或视图序列(Xor[Error, Seq[View]])或可能只是(Xor[Seq[Error],Seq[View])

我怎样才能做到这一点?

scala scala-cats

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

使用Scala Cats将函数列表应用于值

在haskell中,我可以对字符串执行以下操作

let f = sequence [id, reverse]
f "test" 
Run Code Online (Sandbox Code Playgroud)

如果使用Cats更好的方法来解决这个问题,我有点不知所措.我现在有类似的东西

val f = List(fun1,fun2)
val data = "test"

f map {fun => fun(data)} 
Run Code Online (Sandbox Code Playgroud)

是否可以使用Cats实现Sequence或SequenceU的实现?

scala scalaz scala-cats

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

Scala:Cats,OptionT [Future,T]和ApplicativeError

前段时间我开始使用Cats,发现在大多数情况下使用它OptionT非常有用Future[Option[T]].但我面临一个缺点,使用AplicativeError我需要type FutureOption[T] = OptionT[Future, X]为匹配F[_]所需的类型定义类型别名,AplicativeError并明确指定我的表达式的类型FutureOption[T].

type FutureOption[T] = OptionT[Future, T] // definition to match F[_] kind

val x = OptionT.liftF(Future.failed(new Exception("error"))) : FutureOption[String] // need to specify type explicitly
x.recover {
  case NonFatal(e) => "fixed"
}
Run Code Online (Sandbox Code Playgroud)

如果我删除了我的表达式的类型定义和显式类型规范,那么recover因为OptionT[Future, T]不匹配将无法使用F[_],因此无法将其隐式转换为AplicativeErrorOps.

不幸的是,下面的例子不起作用,因为没有recover方法.

val x = OptionT.liftF(Future.failed(new Exception("error")))
x.recover {
  case NonFatal(e) => "fixed"
}
Run Code Online (Sandbox Code Playgroud)

有没有办法避免这种样板代码?至少我想避免明确指定表达式类型FutureOption[T].

scala scala-cats

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

笛卡儿三种名单与猫的产品

假设我需要压缩三个列表来获取三元组列表.我可以这样写:

import cats._
import cats.data._
import cats.implicits._

(List(1, 2) |@| List(3, 4) |@| List(5, 6)) map {case (a, b, c) => (a, b, c)}
res1: List[(Int, Int, Int)] = List((1,3,5), (1,3,6), (1,4,5), (1,4,6), (2,3,5), (2,3,6), (2,4,5), (2,4,6))
Run Code Online (Sandbox Code Playgroud)

你能简化一下吗?

scala cartesian-product scala-cats

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

cats-effect:如何将Map [x,IO [y]]转换为IO [Map [x,y]]

我有一个像这样的字符串到IO的映射Map[String, IO[String]],我想将其转换为IO[Map[String, String]].怎么做?

io scala io-monad scala-cats

4
推荐指数
2
解决办法
261
查看次数

Scala中依赖注入的阅读器的组成

这是一个简单的服务示例,其方法返回reader:

trait Service1_1{
  def s1f1:Reader[Map[String,Int],Int] =
    Reader(_("name"))

  def s1f2:Reader[Map[String,Int],Int] =
    Reader(_("age"))
}
Run Code Online (Sandbox Code Playgroud)

这是一个服务使用者,它接受参数,映射并返回读取器本身:

trait Service1_2 {
  def s12f1(i:Int, map:Map[String,Int]):Reader[Service1_1, Int] =
    Reader(s => {
      val r = for {
        r1 <- s.s1f1
        r2 <- s.s1f2
      } yield r1 + r2
      r.run(map) + i
    })
}
Run Code Online (Sandbox Code Playgroud)

好的,要使用Service1_2.s12f1,我必须在参数列表中具有map:

object s1 extends Service1_1
object s2 extends Service1_2
val r = s2.s12f1(3, Map("age"-> 1, "name"-> 2)).run(s1)
Run Code Online (Sandbox Code Playgroud)

问题:如何实施Service1_2.s12f2

trait Service1_2 {
  def s2f2 = ???
}
Run Code Online (Sandbox Code Playgroud)

为了能够像这样运行它:

s2.s2f2(2)
  .run(s1)
  .run(Map("age"-> 1, "name"-> 2)) …
Run Code Online (Sandbox Code Playgroud)

dependency-injection scala composition reader-monad scala-cats

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

半组类型类(任意),组合稍有改变

使用cats.Semigroup可以这样写:

import cats.Semigroup
import cats.implicits._

val l1: String Either Int = Left("error")
val r1: String Either Int = Right(1)
val r2: String Either Int = Right(2)

l1 |+| r1 // Left("error")
r1 |+| r2 // Right(3)
Run Code Online (Sandbox Code Playgroud)

我希望有一个同样惯用的运算符(类似combine),其工作方式如下:

  • 如果Right我的计算中至少有一个,则返回一个Right
  • 如果只有 Left,则返回一个Left

例如:

Right(1) |+| Right(2) // Right(3) 
Right(1) |+| Left("2") // Right(1) 
Left("1") |+| Left("2") // Left("12") // in my particular case the wrapped value here does not really matter (could also be …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala semigroup scala-cats

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

尾递归算法,用于生成图中的所有拓扑顺序

给定一个图,我需要生成所有拓扑顺序。例如,给定下图:

在此处输入图片说明

我想生成所有拓扑顺序,这些顺序是:

  • 2 4 7 5
  • 2 7 4 5
  • 2 4 5 7

因为可能存在许多拓扑顺序,所以我需要延迟生成它们。当前,我有一个递归工作的实现,并且可以在scala-graph库的顶部进行工作:

import scalax.collection.Graph
import scalax.collection.GraphPredef._
import scalax.collection.GraphEdge._

import scala.collection.mutable.ArrayStack
import scala.collection.Set

def allTopologicalSorts[T](graph: Graph[T, DiEdge]): Stream[List[graph.NodeT]] = {
  val indegree: Map[graph.NodeT, Int] = graph.nodes.map(node => (node, node.inDegree)).toMap

  def isSource(node: graph.NodeT): Boolean = indegree.get(node).get == 0
  def getSources(): Set[graph.NodeT] = graph.nodes.filter(node => isSource(node))

  def processSources(sources: Set[graph.NodeT], indegrees: Map[graph.NodeT, Int], topOrder: List[graph.NodeT], cnt: Int): Stream[List[graph.NodeT]] = {
    if (sources.nonEmpty) {
      // `sources` contain all …
Run Code Online (Sandbox Code Playgroud)

scala tail-recursion graph topological-sort scala-cats

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

究竟何时需要使用State Monad或.copy?

我在haskell的书中看到了一个示例,其中创建了一个简单的堆栈(推送,弹出),并在他们使用.put(..)或.pop()更新堆栈时始终返回monad状态。

提醒一下,该示例类似于以下内容:

pop :: State Stack Int  
pop = State $ \(x:xs) -> (x,xs)  

push :: Int -> State Stack ()  
push a = State $ \xs -> ((),a:xs) 
Run Code Online (Sandbox Code Playgroud)

这是有道理的,但是在看到此示例后,我开始怀疑我的域实体(比如说客户)。现在,我只是在每次要更新它(例如年龄)的东西时,都使用.copy()返回一个新的updated-Customer,就像许多文档中指出的那样,而不使用任何State monad。我使用.copy()的方式没有什么特别的:

case class Customer(age: Int, name: String) {
   def updateAge(newAge: Int): Customer = {
       this.copy(age = newAge)
   }
}
Run Code Online (Sandbox Code Playgroud)

但是,我渴望看到的是,我不仅要返回更新后的副本,还必须返回State Monad,但是到目前为止,我还没有看到任何这样的示例(我自己学习),因此我感到困惑。我的印象是,有时会使用.copy(),而在其他不同情况下会使用State Monad,但是两者都管理State .....

每当我更新客户年龄时,是否应该退回State Monad?

haskell scala scala-cats

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