我最近开始学习scala,并且我遇到了::(cons)函数,它在一个列表前面.
在"Scala编程"一书中,它指出没有附加函数,因为附加到列表具有性能o(n)而前置函数具有o(1)的性能
有些事情让我觉得这个说法错了.
性能是否依赖于实现?是不是可以简单地使用前向和后向链接实现列表并将第一个和最后一个元素存储在容器中?
我想的第二个问题是,当我有一个列表时,我应该做什么,比如说1,2,3,我想在它的末尾添加4个?
Either类似乎很有用,使用它的方法非常明显.但后来我看了API文档,我很困惑:
def joinLeft [A1 >: A, B1 >: B, C] (implicit ev: <:<[A1, Either[C, B1]]):
Either[C, B1]
Joins an Either through Left.
def joinRight [A1 >: A, B1 >: B, C] (implicit ev: <:<[B1, Either[A1, C]]):
Either[A1, C]
Joins an Either through Right.
def left : LeftProjection[A, B]
Projects this Either as a Left.
def right : RightProjection[A, B]
Projects this Either as a Right.
Run Code Online (Sandbox Code Playgroud)
我如何处理投影,如何调用连接?
Google只是向我指出了API文档.
这可能只是"不关注幕后人"的情况,但我不这么认为.我认为这很重要.
为什么编译器不能翻译Scala
(1,2,3,4,5,6).foldRight(10)(_ * _)
Run Code Online (Sandbox Code Playgroud)
与Java等效
final int[] intArray = new int[]{1,2,3,4,5,6};
int accumulator = 10;
for(int i = intArray.legth - 1; i >=0; i--) {
accumulator = intArray[i] * accumulator;
}
Run Code Online (Sandbox Code Playgroud)
问题是:为什么foldLeft和reduceLeft是尾递归的,但它们的右对手不是?
这里有链接说右手不是尾递归.我在问为什么会这样.
我需要将Iterable [[Throwable,String]]减少为[Throwable,Iterable [String]].我不知道这个操作是否相当普遍,在Iterable特征上没有发现任何内容.所以我写了这个函数:
def reduce[A, B](xs: Iterable[Either[A, B]]): Either[A, Iterable[B]] =
xs.collectFirst {
case Left(x) => x
} match {
case Some(x) => Left(x)
case None => Right(xs.collect{case Right(y)=> y})
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我找到一个更好的方法,如果这不是吗?
如何转换List[Either[String, Int]]为Either[List[String], List[Int]]使用类似于cats sequence的方法?例如, xs.sequence在以下代码中
import cats.implicits._
val xs: List[Either[String, Int]] = List(Left("error1"), Left("error2"))
xs.sequence
Run Code Online (Sandbox Code Playgroud)
返回,Left(error1)而不是required Left(List(error1, error2))。
凯文·赖特的答案表明
val lefts = xs collect {case Left(x) => x }
def rights = xs collect {case Right(x) => x}
if(lefts.isEmpty) Right(rights) else Left(lefts)
Run Code Online (Sandbox Code Playgroud)
哪个返回Left(List(error1, error2)),但是猫是否提供开箱即用的排序方式来收集所有剩余数据?
我有一个任何一个列表,它代表错误:
type ErrorType = List[String]
type FailFast[A] = Either[ErrorType, A]
import cats.syntax.either._
val l = List(1.asRight[ErrorType], 5.asRight[ErrorType])
Run Code Online (Sandbox Code Playgroud)
如果所有这些都正确,我想获得 [A] 的列表,在这种情况下 - List[Int]
如果有任何Either剩余,我想合并所有错误并返回它。
我在 [ How to reduce a Seq[Either[A,B]] to a Each[A,Seq[B]]找到了一个类似的主题
但那是很久以前的事了。例如,其中一个答案提供使用partitionMap,我目前找不到。可能有更好、更优雅的解决方案。使用 scala-cats 的例子会很棒。
我想如何使用它:
for {
listWithEihers <- someFunction
//if this list contains one or more errors, return Left[List[String]]
//if everything is fine, convert it to:
correctItems <- //returns list of List[Int] as right
} yield correctItems
Run Code Online (Sandbox Code Playgroud)
这个 for-comprehension 的返回类型必须是:
Either[List[String], List[Int]]
Run Code Online (Sandbox Code Playgroud) 略微简化,我的问题来自一个字符串列表input,我想用函数parse返回解析Either[String,Int].
然后list.map(parse)返回一个Eithers 列表.该程序的下一步是格式化错误消息,总结所有错误或传递解析的整数列表.
让我们来称呼我正在寻找的解决方案partitionEithers.
调用
partitionEithers(List(Left("foo"), Right(1), Left("bar")))
Run Code Online (Sandbox Code Playgroud)
会给
(List("foo", "bar"),List(1))
Run Code Online (Sandbox Code Playgroud)
在标准库中找到这样的东西是最好的.如果没有某种清洁,惯用和有效的解决方案,那将是最好的.还有一些高效的实用功能我可以粘贴到我的项目中就行了.