我在哪里可以找到Lang规范或任何博客中的参考如何阅读这些结构:
trait GenericFunctor[->>[_, _ ], ->>>[_, _ ], F[_]] {
def fmap[A, B](f: A ->> B): F[A] ->>> F[B]
}
Run Code Online (Sandbox Code Playgroud)
要么
trait Category[~>[_, _ ]] {
def compose[A, B, C](f: B ~> C)(g: A ~> B): A ~> C
def id[A]: A ~> A
}
Run Code Online (Sandbox Code Playgroud)
如果它是一个类型名称 - 那么代码 F[A] ->>> F[B]不应该是可编译的,但它是
是否有组合现有 Scala 集合函数来实现以下目标的标准方法?或者这是否已经在一些流行的扩展库(如 Scalaz)中定义?
def partialReduceLeft[T](elements: List[T], nextReduction: List[T] => (T, List[T])): List[T] =
if (elements == Nil)
Nil
else {
val (reduction, residual) = nextReduction(elements)
if (residual.length >= elements.length)
throw new Exception("Residual collection from nextReduction function must be smaller than its input collection.")
if (residual == Nil)
List(reduction)
else
reduction :: partialReduceLeft(residual, nextReduction)
}
Run Code Online (Sandbox Code Playgroud)
该函数接受一个集合并应用一个用户定义的函数,该函数返回第一个减少,这可能消耗一个或多个元素。该方法一直持续到所有元素都被消耗掉。
结果集合的大小可能等于或小于输入集合(我相当不科学地将其称为“部分减少左”-因为想知道此类标准函数的确切术语:))。
我的实现不是尾递归的,老实说,我更愿意使用别人的代码!!
我正在尝试使用Scalaz的应用程序构建器来简化一些并行运行一些未来的代码:
import scalaz._, Scalaz._
val fooF: Future [String] = myService.getFoo ()
val barF: Future [String] = myService.getBar ()
val resultF = for {
foo <- fooF
bar <- barF
}
yield { foo + bar }
Run Code Online (Sandbox Code Playgroud)
我明白我应该能够像这样重写上面的代码:
val resultF = (myService.getFoo () |@| myService.getBar ()) {
(foo, bar) => { foo + bar }
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下编译错误:
value |@| is not a member of scala.concurrent.Future[String]
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
给出以下Foo案例类:
scala> case class Foo(x: Int)
defined class Foo
Run Code Online (Sandbox Code Playgroud)
我Foo在构建它之前检查它是否有效validateFoo:
scala> def validateFoo(foo: Foo): \/[String, Foo] =
(if(foo.x > 0) foo.success[String]
else ("invalid foo").failure[Foo]).disjunction
validateFoo: (foo: Foo)scalaz.\/[String,Foo]
Run Code Online (Sandbox Code Playgroud)
最后,f创建一个Foo,然后尝试执行一个IO操作(例如:保存Foo到数据库).
scala> def f(x: Foo): IO[\/[String,Int]] = for {
| foo <- validateFoo(x)
| ioFoo <- IO { foo }
| } yield ioFoo
<console>:19: error: type mismatch;
found : scalaz.effect.IO[Foo]
required: scalaz.\/[?,?]
ioFoo <- IO { foo } …Run Code Online (Sandbox Code Playgroud) 我想我明白了什么顺序.我想知道为什么它不起作用List[ValidationNel].例如:
该sequence罚款的作品List[Option]]
scala> val os = List(1.some, 2.some)
os: List[Option[Int]] = List(Some(1), Some(2))
scala> os.sequence
res10: Option[List[Int]] = Some(List(1, 2))
Run Code Online (Sandbox Code Playgroud)
......但不起作用 List[ValidationNel]
scala> val vs: List[ValidationNel[String, Int]] = List(Success(1), Success(2))
vs: List[scalaz.ValidationNel[String,Int]] = List(Success(1), Success(2))
scala> vs.sequence
<console>:15: error: could not find implicit value for parameter ev:scalaz.Leibniz.===[scalaz.ValidationNel[String,Int],G[B]]
Run Code Online (Sandbox Code Playgroud)
......但sequenceU 确实有效List[ValidationNel]
scala> vs.sequenceU
res14: scalaz.Validation[scalaz.NonEmptyList[String],List[Int]] = Success(List(1, 2))
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么不sequence一起工作List[ValidationNel]?为什么sequenceU要用它?
我正在尝试一些代码来检查Scala中的这些幻灯片Free Monad,并用一些稍微改变的代码创建了一个小项目.
该项目在这里:https://github.com/freewind/free-the-monads
一开始看起来一切都很好,代码干净漂亮:
def insertAndGet() = for {
_ <- Script.insert("name", "Freewind")
value <- Script.get("name")
} yield value
def insertAndDelete() = for {
_ <- Script.insert("name", "Freewind")
_ <- Script.delete("name")
value <- Script.get("name")
} yield value
def insertAndUpdateAndDelete() = for {
_ <- Script.insert("name", "Freewind1")
oriValue <- Script.update("name", "Freewind2")
_ <- Script.delete("name")
finalValue <- Script.get("name")
} yield (oriValue, finalValue)
Run Code Online (Sandbox Code Playgroud)
但是当我的逻辑很复杂时,例如有一些Script[Option[_]],我需要检查选项值以决定做某事,我不能再使用了for-comprehension,代码如下:
private def isLongName(name: String): …Run Code Online (Sandbox Code Playgroud) 假设我们有EitherT[F, String, A].withFilterScalaz 的函数使用了String's Monoid 的零,以便Left在过滤器失败时填写.
因此,没有有意义的错误消息.
我怎么能实现左边的"不积极"形式的东西.
val a: Either[Future, String, Int] = -1.point[EitherT[Future, String, ?]]
val foo = for {
aa <- a
if aa >= 0
} yield aa
Run Code Online (Sandbox Code Playgroud)
只是hacks的方法filter和withFilter方法是否EitherT满足for-comprehension要求?
我在阅读有关scalaz并注意到,我们可以让列表Applicatives到是Applicative的List.
def sequenceA[F[_]: Applicative, A](list: List[F[A]]): F[List[A]] = list match {
case Nil => (Nil: List[A]).point[F]
case x :: xs => (x |@| sequenceA(xs)) {_ :: _}
}
Run Code Online (Sandbox Code Playgroud)
问题是我们可以做相反的事吗?我们可以改造F[List[A]]成List[F[A]]?
在考虑错误并转换IO[E, T]为 an 之后,IO[Nothing, T]我们可以直接将该值称为类型T而不是IO[Nothing, T]。这允许我们返回一个类型的值而T无需使用var和IO.map。有没有办法做到这一点,如果没有,为什么不呢?
ZIO当前的README中没有找到解决方案。
我花了一段时间在Google上搜索了非猫三重等于方法,但除了Scalaz找不到任何东西。不幸的是,我无法===在此库中计算出导入。
有人可以帮忙,非常感谢。
scala ×10
scalaz ×10
applicative ×2
scala-cats ×2
either ×1
equals ×1
filter ×1
monads ×1
refactoring ×1
traversable ×1
zio ×1