gpt4 book ai didi

scala - 使用 Scalaz 在 Scala 中进行带有验证的异步计算

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

正在编写一个完全异步的库来访问远程服务(使用 Play2.0),我正在使用 PromiseValidation创建非阻塞调用,该调用具有一次呈现失败和有效结果的类型。
Promise来自 Play2-scala,其中 Validation来自 Scalaz 。

所以这里是此类函数的示例类型

  • f::A => Promise[Validation[E, B]]
  • g::B => Promise[Validation[E, C]]

  • 到目前为止,很好,现在如果我想编写它们,我可以简单地使用 Promise 的事实。赠送 flatMap ,所以我可以通过理解来做到这一点
    for (
    x <- f(a);
    y <- g(b)
    ) yield y

    好的,我在这里解决了我的问题,因为我没有重复使用 Validation理解内的结果。所以如果我想重用 xg ,这是我能做的
    for (
    x <- f(a); // x is a Validation
    y <- x.fold(
    fail => Promise.pure(x),
    ok => g(ok)
    )
    ) yield y

    很公平,但是这种样板会一遍又一遍地污染我的代码。这里的问题是我有一种像 M[N[_]] 这样的两级 Monadic 结构。 .

    在这个阶段,f° 编程中是否有任何结构可以通过轻松跳过 secong 级别来使用这样的结构:
    for (
    x <- f(a); //x is a B
    y <- g(b)
    ) yield y

    现在,下面是我如何实现类似的东西。

    我创建了一种将两层合二为一的 Monadic 结构,比如 ValidationPromised拉皮条的 Promise用两种方法输入:
    def /~> [EE >: E, B](f: Validation[E, A] => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid =>
    f(valid).promised
    }

    def /~~>[EE >: E, B](f: A => ValidationPromised[EE, B]): ValidationPromised[EE, B] =
    promised flatMap { valid =>
    valid.fold (
    bad => Promise.pure(KO(bad)),
    good => f(good).promised
    )
    }

    这让我可以做这样的事情
          endPoint.service /~~>                                   //get the service
    (svc => //the service
    svc.start /~~> (st => //get the starting elt
    svc.create(None) /~~> //svc creates a new elt
    (newE => //the created one
    newEntry.link(st, newE) /~~> //link start and the new
    (lnk => Promise.pure(OK((st, lnk, newE)))) //returns a triple => hackish
    )
    )
    )

    如我们所见 /~~>flatMap 非常相似但跳过一级。问题是冗长(这就是为什么在 Scala 中存在“for-comprehension”而在 Haskell 中存在“do”)。

    还有一点,我有 /~>就像一个 map也适用于第二级(而不是有效类型 - 第三级)

    所以我的第二个问题是前者的必然结果......我是否正在通过这种结构接近可持续的解决方案?

    抱歉这么长

    最佳答案

    您在这里寻找的概念是 monad transformers .简而言之,monad 变压器补偿 monads not composing通过允许您“堆叠”它们。

    您没有提到您正在使用的 Scalaz 版本,但是如果您查看 scalaz-seven branch ,你会发现 ValidationT .这可用于包装任何 F[Validation[E, A]]ValidationT[F, E, A] , 在你的情况下 F = Promise .如果您更改 fg返回 ValidationT ,然后您可以将代码保留为

    for {
    x ← f(a)
    y ← g(b)
    } yield y

    这会给你一个 ValidationT[Promise, E, B]其结果。

    关于scala - 使用 Scalaz 在 Scala 中进行带有验证的异步计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10968057/

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