Scala 围绕更高种类的类型展开一个选项,寻找一种更惯用的方法
Scala flattening an Option around a higher kinded type, looking for a more idiomatic approach
给定更高的 Kinded 类型 M 和 monad 类型 class,我可以通过 for-comprehension 对 M 中的值进行操作。使用 return 选项的函数,我正在寻找一种比我现有的解决方案更合适的方法来展平这些选项。如下
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
}
}
所以我要更正以下内容:
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.divideBy(i))
还有这种情况,我没有调用第二个 divideBy,而是调用 multiplyBy which returns M[Float]
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.multipleBy(i).map(Some(_))
也许这就是 Monad Transformers 的情况,但我不确定该怎么做。
似乎 monad 转换器可以在这方面为您提供帮助。例如,以下编译,我认为大致符合您的要求:
import scalaz._, Scalaz._
abstract class Calculator[M[_]: Monad] {
def divideBy(x: Float): M[Option[Float]]
def multiplyBy(x: Float): M[Float]
}
class Test[M[_]: Monad](calc: Calculator[M]) {
def doSomething(x: Float): OptionT[M, Float] = for {
y <- OptionT(calc.divideBy(x))
z <- calc.multiplyBy(y).liftM[OptionT]
} yield z
}
现在 doSomething
returns 一个 OptionT[M, Float]
,它是 M[Option[Float]]
的一种包装器,允许您使用 [=14] 中的所有内容=] 一元化。要从 OptionT[M, Float]
取回 M[Option[Float]]
,您可以使用 run
方法。
给定更高的 Kinded 类型 M 和 monad 类型 class,我可以通过 for-comprehension 对 M 中的值进行操作。使用 return 选项的函数,我正在寻找一种比我现有的解决方案更合适的方法来展平这些选项。如下
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
}
}
所以我要更正以下内容:
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.divideBy(i))
还有这种情况,我没有调用第二个 divideBy,而是调用 multiplyBy which returns M[Float]
y.fold[M[Option[Float]]](implicitly[Monad[M]].point(None))(i => calc.multipleBy(i).map(Some(_))
也许这就是 Monad Transformers 的情况,但我不确定该怎么做。
似乎 monad 转换器可以在这方面为您提供帮助。例如,以下编译,我认为大致符合您的要求:
import scalaz._, Scalaz._
abstract class Calculator[M[_]: Monad] {
def divideBy(x: Float): M[Option[Float]]
def multiplyBy(x: Float): M[Float]
}
class Test[M[_]: Monad](calc: Calculator[M]) {
def doSomething(x: Float): OptionT[M, Float] = for {
y <- OptionT(calc.divideBy(x))
z <- calc.multiplyBy(y).liftM[OptionT]
} yield z
}
现在 doSomething
returns 一个 OptionT[M, Float]
,它是 M[Option[Float]]
的一种包装器,允许您使用 [=14] 中的所有内容=] 一元化。要从 OptionT[M, Float]
取回 M[Option[Float]]
,您可以使用 run
方法。