加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用Scalaz在Scala中使用Validation进行异步计算

发布时间:2020-12-16 19:16:17 所属栏目:安全 来源:网络整理
导读:正在编写一个完全异步库来访问远程服务(使用Play2.0),我正在使用Promise和Validation来创建非阻塞调用,它具有一次显示失败和有效结果的类型. Promise来自Play2-scala,其中验证来自scalaz. 所以这是这类函数的例子 f :: A =承诺[验证[E,B]] g :: B =承诺[验证
正在编写一个完全异步库来访问远程服务(使用Play2.0),我正在使用Promise和Validation来创建非阻塞调用,它具有一次显示失败和有效结果的类型.

Promise来自Play2-scala,其中验证来自scalaz.

所以这是这类函数的例子

> f :: A =>承诺[验证[E,B]]
> g :: B =>承诺[验证[E,C]]

到目前为止,这么好,现在如果我想编写它们,我可以简单地使用Promise呈现flatMap的事实,所以我可以用for-comprehension来做

for (
   x <- f(a);
   y <- g(b)
) yield y

好的,我在这里找到了我的问题的快捷方式,因为我没有在for-comprehension中重用验证结果.因此,如果我想在g中重复使用x,那么我就是这样做的

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] = 
    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”的原因).

还有一点,我是/?>它也像地图一样但是在第二级工作(而不是有效类型 – 第三级)

所以我的第二个问题是前者的必然结果……我是否正在采用这种结构来实现可持续解决方案?

抱歉,那么久

解决方法

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

你没有提到你正在使用的Scalaz版本,但是如果你查看scalaz-seven branch,你会发现ValidationT.这可以用来将任何F [验证[E,A]]包装到ValidationT [F,E]中,A],在你的情况下F =承诺.如果更改f和g以返回ValidationT,则可以将代码保留为

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

这将为您提供ValidationT [Promise,E,B].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读