gpt4 book ai didi

scala - 我可以使用 monad 转换器来简化这个组合吗?

转载 作者:行者123 更新时间:2023-12-04 15:14:17 25 4
gpt4 key购买 nike

假设我有

type VS[A] = Validation[String, A]

val v: VS[Option[A]]
val f: A => VS[B]

我想得到 VS[Option[B]] 类型的结果但如果 vSuccess(None) ,结果也应该是 Success(None) .下面是一个例子:
scala> val v: VS[Option[String]] = some("4.5").success
v: VS[Option[String]] = Success(Some(4.5))

scala> val f = (s : String) => (try { s.toInt.success } catch { case x => x.getMessage.fail }): VS[Int]
f: String => VS[Int] = <function1>

然后:
scala> import Validation.Monad._
import Validation.Monad._

scala> (v map2 f map (_.sequence)).join
res4: scalaz.Validation[String,Option[Int]] = Failure(For input string: "4.5")

成功案例是:
scala> val v: VS[Option[String]]= some("5").success
v: VS[Option[String]] = Success(Some(5))

scala> (v map2 f map (_.sequence)).join //UGLY composition
res7: scalaz.Validation[String,Option[Int]] = Success(Some(5))

空的情况是:
scala> val v: VS[Option[String]]= none[String].success
v: VS[Option[String]] = Success(None)

scala> (v map2 f map (_.sequence)).join
res6: scalaz.Validation[String,Option[Int]] = Success(None)

有没有“更好”的方法来做到这一点(可能涉及 kleisli 组合或 monad 转换器)?

最佳答案

monad 转换器 OptionT在这里完全满足您的要求,它的 flatMapF方法使使用成为一种干净的单线。

我将使用 Scalaz 7 的析取类型 ( \/ ) 而不是 Validation在这个例子中,因为后者不是 Scalaz 7 中的 monad,但原理是相同的。

import scalaz._, std.option._, syntax.id._, syntax.monad._

type DS[+A] = String \/ A
type ODS[A] = OptionT[DS, A]

def f(s: String) = try s.toInt.right catch { case e => e.getMessage.left }

现在我们可以这样写:
scala> val v = OptionT(some("4.5").point[DS])
v: scalaz.OptionT[DS,java.lang.String] = OptionT(\/-(Some(4.5)))

scala> (v flatMapF f).run
res0: DS[Option[Int]] = -\/(For input string: "4.5")

或等效地:
scala> ("4.5".point[ODS] flatMapF f).run
res1: DS[Option[Int]] = -\/(For input string: "4.5")

或者成功案例:
scala> ("4".point[ODS] flatMapF f).run
res2: DS[Option[Int]] = \/-(Some(4))

或空箱:
scala> (OptionT(none.point[DS]) flatMapF f).run
res3: DS[Option[Int]] = \/-(None)

如预期的。

关于scala - 我可以使用 monad 转换器来简化这个组合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10853788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com