我正在尝试使用猫库,但我很难在导入和创建的东西之间导航.我的问题如下:
sealed trait Checks
case class CheckViolation(id: Long, msg: String) extends Checks
case class ChecksPassed(ids: Seq[Long]) extends Checks
Run Code Online (Sandbox Code Playgroud)
这是我想要使用的数据结构.每个违规都应该作为具有msg的对象保存,传递的检查可以聚合为仅保存id.
object BusinessRuleSetValidation extends App {
type BRValidationResult = Validated[NonEmptyList[CheckViolation], ChecksPassed]
def run(): BRValidationResult = {
implicit val monoidChecksPassed = new Monoid[ChecksPassed] {
override def empty: ChecksPassed = ChecksPassed(Seq())
override def combine(x: ChecksPassed, y: ChecksPassed): ChecksPassed = ChecksPassed(x.ids ++ y.ids)
}
val check1: BRValidationResult = valid(ChecksPassed(2L))
val check2: BRValidationResult = invalidNel(CheckViolation(1, "This check was violated"))
val check3: BRValidationResult = invalidNel(CheckViolation(2, "This is …Run Code Online (Sandbox Code Playgroud) 我目前正在使用EitherT堆叠Futures和Eithers:
type ErrorOr[A] = Either[Error, A]
def getAge: Future[ErrorOr[Int]] = ???
def getDob(age: Int): ErrorOr[LocalDate] = ???
for {
age <- EitherT(getAge)
dob <- EitherT.fromEither[Future](getDob(age))
} yield dob
Run Code Online (Sandbox Code Playgroud)
我现在想介绍一下Writer monad ie
type MyWriter[A] = Writer[Vector[String], ErrorOr[A]]
def getAge: Future[MyWriter[Int]] = ???
def getDob(age: Int): MyWriter[LocalDate] = ???
Run Code Online (Sandbox Code Playgroud)
我的问题是,对调用getAge和getDob调用进行排序的最佳方法是什么?我知道monads可以堆叠,Future -> Writer -> Either但是我可以继续EitherT在这种情况下使用吗?如果是这样的话?
我正在阅读高级Scala With Cats.我在函子描述(第59页)中坚持这个例子:
object FunctorsDemo extends App {
import cats.instances.function._
import cats.syntax.functor._
val func1 = (x: Int) => x.toDouble
val func2 = (y: Double) => y * 2
val func3 = func1.map(func2) // wrong line for me
}
Run Code Online (Sandbox Code Playgroud)
在书中一切都很好,但我有这个例外:
Error:(10, 21) value map is not a member of Int => Double
val func3 = func1.map(func2)
Run Code Online (Sandbox Code Playgroud)
无法理解我做错了什么.
是否有可能以某种方式将解决方案扩展为总和类型?
sealed trait Group
case class A extends Group
case class B extends Group
case class C extends Group
def divide(l : List[Group]): //Something from what I can extract List[A], List[B] and List[C]
Run Code Online (Sandbox Code Playgroud) 我有一些使用Monix Observable进行文件流处理的代码.为了测试这段代码,我希望我所做的操作Observable是独立的,所以我也可以在任何其他数据结构上执行它们List.这就是我编写以下代码来抽象底层数据结构的原因:
def permutations[F[_] : Applicative : FunctorFilter : SemigroupK](chars: F[Char]): F[F[Char]] = {
Range.inclusive('a', 'z').map(_.toChar)
.map { c ?
FunctorFilter[F].filter(chars)(Character.toLowerCase _ andThen (_ != c))
}
.map(Applicative[F].pure)
.reduceLeft(SemigroupK[F].combineK)
}
Run Code Online (Sandbox Code Playgroud)
让我烦恼的是,这段代码创建了许多中间数据结构.是否有我可以使用的类型类使这个过程更有效?将一个数据结构提升到另一个数据结构而没有太多开销的东西,比如LiftIO项目集合?
我有以下代码:
import cats.effect.IO
import cats.data.State
import cats.data.StateT
import cats.implicits._
import cats.effect.LiftIO
abstract class Example {
object implicits {
implicit def myEffectLiftIO: LiftIO[IOGameplay] =
new LiftIO[IOGameplay] {
override def liftIO[A](ioa: IO[A]): IOGameplay[A] = {
StateT.liftF(ioa)
}
}
}
type Gameplay[A] = State[GameState, A]
type IOGameplay[A] = StateT[IO, GameState, A]
type EitherDirection[A] = Either[Throwable, A]
type Map = Array[Array[FieldType]]
sealed trait FieldType
case class GameState(map: Map, block: Block)
case class Block(f1: Field, f2: Field)
case class Field()
import implicits._
val L = …Run Code Online (Sandbox Code Playgroud) 因此,我有一个特定的函数,只有在特定条件为真时才需要调用。如果它是错误的,我认为它是正确的。
我将使用EitherT.cond,但问题是我函数的返回类型是Future [Either [ErrorType,Unit]],所以它不适合我。这是我想要的代码:
def callEitherFunction: Future[Either[ErrorType, Unit]]
for {
_ <- if (condition) {
EitherT(callEitherFunction)
} else {
Either.right[ErrorType, Unit](()).toEitherT[Future]
}
} yield {
//Some actions
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更优雅的方法。将不胜感激。
scala monad-transformers either conditional-statements scala-cats
我想知道是否存在一个函数(在 scala 或猫中)忽略flatMap. 例如
Some("ignore this").ignoreArgumentFlatMap(Some("result"))
Run Code Online (Sandbox Code Playgroud)
这将与
Some("ignore this").flatMap(_ => Some("result"))
Run Code Online (Sandbox Code Playgroud) 当我在 Scala 中有一个函数时:
def toString[T: Show](xs: T*): String = paths.map(_.show).mkString
Run Code Online (Sandbox Code Playgroud)
以及范围内的以下类型类实例:
implicit val showA: Show[MyTypeA]
implicit val showB: Show[MyTypeB]
Run Code Online (Sandbox Code Playgroud)
我可以通过toString以下方式使用函数:
val a1: MyTypeA
val a2: MyTypeA
val stringA = toString(a1, a2)
val b1: MyTypeB
val b2: MyTypeB
val stringB = toString(b1, b2)
Run Code Online (Sandbox Code Playgroud)
但我不能叫toString混合型的参数MyTypeA和MyTypeB:
// doesn't compile, T is inferred to be of type Any
toString(a1, b1)
Run Code Online (Sandbox Code Playgroud)
是否有可能以toString一种可以混合不同类型的参数(但仅限于Show类型类可用)的方式重新定义?
请注意,我知道 cat show interpolator 可以解决这个特定的例子,但我正在寻找一种也可以应用于不同情况的解决方案(例如toNumber)。
我也知道通过.show在将参数传递给toString …
我正在尝试将我的头围绕在 Cats 中的 Semigroupals 上。以下是 Underscore 的“Scala with Cats”中的陈述。
cats.Semigroupal是一个允许我们组合上下文的类型类
trait Semigroupal[F[_]] {
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
Run Code Online (Sandbox Code Playgroud)
参数
fa和fb彼此独立:在将它们传递给 之前,我们可以按任一顺序计算它们product。这与 形成对比flatMap,后者对其参数施加了严格的顺序。
所以基本上,我们也应该能够结合两个Either上下文,但这似乎不起作用:
import cats.instances.either._
type ErrorOr[A] = Either[Vector[String], A]
Semigroupal[ErrorOr].product(Left(Vector("Error 1")), Left(Vector("Error 2")))
// res3: ErrorOr[Tuple2[Nothing, Nothing]] = Left(Vector("Error 1"))
Run Code Online (Sandbox Code Playgroud)
如果 semigroupal 的 USP 急切地执行独立操作,则必须在传递给之前对两者进行评估product,但我们无法获得组合结果。
我们可能期望
product应用于Either累积错误而不是快速失败。同样,也许令人惊讶的是,我们发现它product实现了与 相同的 fail?fast 行为flatMap。
这是否与使用替代方法能够组合任何相同类型的上下文的原始前提相悖?
为了确保一致的语义,Cats 的 Monad(它扩展了 Semigroupal)根据
map …
scala ×10
scala-cats ×10
monads ×2
cats-effect ×1
either ×1
implicit ×1
monix ×1
polymorphism ×1
scalaz ×1
typeclass ×1