标签: for-comprehension

反求理解

如何做Scala相当于这个Java代码:

int i = 0;
for(String x: xs) {
    for(String y : ys) {
        foo(x, y, i);
        i+=10;
    }
}
Run Code Online (Sandbox Code Playgroud)

for-loop scala for-comprehension

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

Scala - 按顺序依次执行任意数量的Futures

我正在试图找出按序列执行一系列期货的最佳方式,其中一个Future的执行取决于之前的.我试图为任意数量的期货做这件事.

用户案例:

  • 我从我的数据库中检索了许多ID.
  • 我现在需要检索Web服务上的一些相关数据.
  • 一旦我找到了有效的结果,我想停止.
  • 我只关心成功的结果.

并行执行这些并且然后解析返回的结果集合不是一种选择.我必须一次执行一个请求,并且只有在前一个请求没有返回任何结果时才执行下一个请求.

目前的解决方案是沿着这些方向.使用foldLeft执行请求,然后仅在前一个未来满足某些条件时评估下一个未来.

def dblFuture(i: Int) = { i * 2 }
val list = List(1,2,3,4,5)
val future = list.foldLeft(Future(0)) {
  (previousFuture, next) => {
    for {
      previousResult <- previousFuture
      nextFuture <- { if (previousResult <= 4) dblFuture(next) else previousFuture }
    } yield (nextFuture)
  }
}
Run Code Online (Sandbox Code Playgroud)

这方面的一个重大缺点是:a)我一直处理所有项目,即使我得到了一个我很满意的结果,并且b)一旦我找到了我想要的结果,我就会继续评估谓词.在这种情况下,它是一个简单的if,但实际上它可能更复杂.

我觉得我错过了一个更优雅的解决方案.

scala future sequential for-comprehension foldleft

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

为什么For Comprehension生成器抑制Option类型?

在下面的代码中,版本1给出了正确的结果.我在V2中做了一个小变化.无值已经消失,这是好的,因为这是For Expression的工作方式.但是什么原因导致V2中的yield输出不再尊重myList.lift()返回的数据类型,这是一个Option(如V1所示)?

val myList = List(12, 34, "ABC")
Run Code Online (Sandbox Code Playgroud)

版本1

for { i <- (0 to 3).toList } yield myList.lift(i)
// res1: List[Option[Any]] = List(Some(12), Some(34), Some(ABC), None)
Run Code Online (Sandbox Code Playgroud)

版本2

for { 
  i <- (0 to 3).toList 
  x <- myList.lift(i)
} yield x
// res2: List[Any] = List(12, 34, ABC)
Run Code Online (Sandbox Code Playgroud)

scala for-comprehension

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

为了理解两个相同长度的数组

我有两个Seq[Array[Byte]]数组:

var o1: Seq[Array[Byte]]
var o2: Seq[Array[Byte]]
//...
Run Code Online (Sandbox Code Playgroud)

我需要改变o1数组的Seq,这样如果数组的长度非零,则每个数组都o1被替换o2为相同位置的数组.o2

是否有可能与理解?

scala for-comprehension

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

用于理解的Scala模式匹配

在 Scala 中,您是否可以有一个 for 理解,它遍历对象列表,然后根据元素的一个属性的类型创建一个值数组?所以假设我有一个元素列表,每个元素都有一个属性,并且属性可以是不同的类型......

for (element <- elementList) element.attribute match {
 case a: Type1 => "Type1"
 case a => "All Types"
}
Run Code Online (Sandbox Code Playgroud)

然后生成的 Array 将是一个具有类似值的数组

Array("Type1", "Type1", "All Types", "Type1", "All Types", "All Types", "All Types", "All Types") 
Run Code Online (Sandbox Code Playgroud)

scala pattern-matching for-comprehension

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

Scala:以理解的方式迭代数组的索引,但确保结果类型与数组类型相同

我知道在理解中找到的第一个序列的序列类型定义了理解的输出类型。但是我需要在不牺牲理解语法使用的情况下解决这个问题。

假设我有一些Array[Double]v和被叫一些复杂的谓词函数condition是基于该指数v,而如果condition(i)计算结果为真实的,那么我想保留的元素v。与用法类似filter,区别在于过滤发生在索引上,而不是上v

我想通过对索引的理解来有效地表达这一点,但是我希望结果的类型为Array[Double]而不是的类型Array.indices

这是一个最小的示例,其中condition只是一个计算索引是否为偶数的玩具示例。实际用例涉及检查2D数组中的某些图像渐变条件是否正确的索引,但是想法与此简单示例相同。

scala> val v = Array[Double](8.0, 9.0, 10.0, 11.0, 12.0)
v: Array[Double] = Array(8.0, 9.0, 10.0, 11.0, 12.0)

scala> def condition(x: Int): Boolean = {x % 2 == 0} // but could be complex
condition: (x: Int)Boolean

scala> for (i <- v.indices if condition(i)) yield v(i)
res136: scala.collection.immutable.IndexedSeq[Double] = Vector(8.0, 10.0, 12.0)
Run Code Online (Sandbox Code Playgroud)

理解的输出是类型, …

scala sequence resulttype for-comprehension

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

对于理解不完全使用Reader进行单元测试的步骤

我有一个带有单元测试的无标签最终实现,当我运行单元测试时,仅第一步被调用,其余部分不被调用。

这是测试目标:

class NameThing[F[_]: Monad](implicit console: Console[F]) {

  def program: F[Unit] = for {
    _ <- console.prompt
    rawName <- console.read
    fullName = parse(rawName)
    _ <- console.display(fullName)
  } yield ()

  def parse(rawName:String):FullName = {
    val parts = rawName.split(" ")
    FullName(parts(0), parts(1))
  }
}
Run Code Online (Sandbox Code Playgroud)

单元测试是:

implicit object TestConsole extends Console[Test] {
      override def prompt: Test[Unit] = {
        println("ok1")
        Reader(TestEnv => TestEnv.prompt)
      }
      override def read: Test[String] =  {
        println("ok2")
        Reader(TestEnv => TestEnv.read)
      }
      override def display(fullName: FullName): Test[Unit] = {
        println("ok3")
        Reader(TestEnv …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala for-comprehension reader-monad scala-cats

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

对于Future [String]和Future [List [String]]的理解

简化代码:

val one: Future[String] = Future("1")
val many: Future[List[String]] = Future({"1","2","3"})

for { 
  a <- one
  b <- many
} yield {
  doSomething(a,b) // Type mismatch, expected String, actual: List[String]
}
Run Code Online (Sandbox Code Playgroud)

我想发生的事情是每两个(一对)呼叫并获得输出列表

 {doSomething("1","1"),doSomething("1","2"),doSomething("1","3")}
Run Code Online (Sandbox Code Playgroud)

即使一个是a Future[String]而另一个是a ,我也可以使用它进行理解Future[List[String]]吗?

scala for-comprehension

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

为什么带有收益的for循环累积到Map中而不​​是List中?

我有以下代码:

val dummy = Map(1 -> Map(2 -> 3.0,
                         4 -> 5.0),
                6 -> Map(7 -> 8.0))

val thisIsList = for (x <- dummy; y <- x._2.keys) yield s"(${x._1}, ${y})"
println(thisIsList)  // List((1, 2), (1, 4), (6, 7))

val thisIsMap = for (x <- dummy; y <- x._2.keys) yield new Tuple2(x._1, y)
println(thisIsMap)   // Map(1 -> 4, 6 -> 7) - this is not what I want    
Run Code Online (Sandbox Code Playgroud)

我希望第二个语句产生一个元组列表,但是它返回一个Map。我在这里找到了一个解释说明:生成一个元组序列而不是map来说明为什么返回Map,但是在这种情况下,我仍在努力寻找一种优雅的方法来返回元组列表。

scala for-comprehension scala-collections

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

scala中这是什么类型的表达?

考虑到x,p,r是从前面的表达式求出的,则在<-之后=之后发生的情况

val a = for{
 x <- y
 p = q (x)
 r <- s (p)
} yield (something(p.something, r.something))
Run Code Online (Sandbox Code Playgroud)

functional-programming scala for-comprehension

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