Given a higher Kinded Type M, and a monad type class, I can operate on values within M through a for-comprehension. Working with a function that return Options, im looking for a more appropriate way to flatten these options than the solution I have. This is as follows
class Test[M[+_]:Monad](calc:Calculator[M]) {
import Monad._
def doSomething(x:Float):M[Option[Float]] = {
for {
y:Option[Float] <- calc.divideBy(x) // divideBy returns M[Option[Float]]
z:Option[Float] <- y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.divideBy(i))
} yield z
}
}
So its the following I'm looking to correct:
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.divideBy(i))
Also the case where instead of calling the second divideBy, I call multiplyBy which returns M[Float]
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.multipleBy(i).map(Some(_))
Maybe this is a case for Monad Transformers but Im not sure how to go about it.
It seems likely that monad transformers can help you here. For example, the following compiles and I think does roughly what you want:
Now
doSomething
returns anOptionT[M, Float]
, which is kind of wrapper forM[Option[Float]]
that allows you to work with the contents all the way inside theOption
monadically. To get back anM[Option[Float]]
from theOptionT[M, Float]
you can just use therun
method.