将函数提升到 Scala cat 中的 monad 转换器
Lifting functions to monad transformers in Scala cats
假设有一个具有不同签名的抽象方法的特征(见下文)。为了便于理解,我可以为每个抽象方法定义相同的签名 Result[A]
。
但是,为了简化 trait 的子类,我想为方法 2 和 3 保留更简单的签名。
import cats.data.{EitherT, Reader}
trait Domain{
type Read[A] = Reader[BoundsProblem, A]
type Result[A] = EitherT[Read, String, A]
def stepSize( s: State, direction: Direction): Result[Double] //depends on an injected context, can fail
def takeStep( s: State, dir: Direction, stepSize: Double): Read[Variable] //depends on context, can't fail
def calculate(x: Variable): (Double, Gradient) //context-independent, can't fail
//doesn't compile:
def iteration(s: State, dir: Direction) = for{
tee <- stepSize(s, dir)
x <- takeStep(s, dir, tee)
r <- calculate(x)
} yield r
}
我的问题是如何在 Cats 中完成此操作。 (我尝试将 takeStep
提升到 EitherT[Read, String, A]
没有成功。)还是我最好只为每个方法定义相同的 Result[A]
?
尝试
def iteration(s: State, dir: Direction): Result[(Double, Gradient)] = for{
tee <- stepSize(s, dir)
x <- EitherT.right(takeStep(s, dir, tee))
r = calculate(x)
} yield r
或
def iteration(s: State, dir: Direction): Result[(Double, Gradient)] = for{
tee <- stepSize(s, dir)
x <- EitherT.right(takeStep(s, dir, tee))
} yield calculate(x)
假设有一个具有不同签名的抽象方法的特征(见下文)。为了便于理解,我可以为每个抽象方法定义相同的签名 Result[A]
。
但是,为了简化 trait 的子类,我想为方法 2 和 3 保留更简单的签名。
import cats.data.{EitherT, Reader}
trait Domain{
type Read[A] = Reader[BoundsProblem, A]
type Result[A] = EitherT[Read, String, A]
def stepSize( s: State, direction: Direction): Result[Double] //depends on an injected context, can fail
def takeStep( s: State, dir: Direction, stepSize: Double): Read[Variable] //depends on context, can't fail
def calculate(x: Variable): (Double, Gradient) //context-independent, can't fail
//doesn't compile:
def iteration(s: State, dir: Direction) = for{
tee <- stepSize(s, dir)
x <- takeStep(s, dir, tee)
r <- calculate(x)
} yield r
}
我的问题是如何在 Cats 中完成此操作。 (我尝试将 takeStep
提升到 EitherT[Read, String, A]
没有成功。)还是我最好只为每个方法定义相同的 Result[A]
?
尝试
def iteration(s: State, dir: Direction): Result[(Double, Gradient)] = for{
tee <- stepSize(s, dir)
x <- EitherT.right(takeStep(s, dir, tee))
r = calculate(x)
} yield r
或
def iteration(s: State, dir: Direction): Result[(Double, Gradient)] = for{
tee <- stepSize(s, dir)
x <- EitherT.right(takeStep(s, dir, tee))
} yield calculate(x)