Reputation: 565
Suppose there's a trait with abstract methods having different signatures (see below). To enable for-comprehension, I could define the same signature Result[A]
for every abstract method.
However, to simplify trait's subclasses, I'd like to keep the simpler signatures for methods 2 and 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
}
My question is how this could be done in Cats. (My attempts to lift takeStep
to EitherT[Read, String, A]
didn't succeed.) Or am I better off just defining the same Result[A]
for each method?
Upvotes: 0
Views: 354
Reputation: 51648
Try
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
or
def iteration(s: State, dir: Direction): Result[(Double, Gradient)] = for{
tee <- stepSize(s, dir)
x <- EitherT.right(takeStep(s, dir, tee))
} yield calculate(x)
Upvotes: 1