and*_*lla 7 scala scalaz playframework-2.0
正在编写一个完全异步的库来访问远程服务(使用Play2.0),我正在使用Promise并Validation创建非阻塞调用,它具有一次显示失败和有效结果的类型.
Promise来自Play2-scala,Validation来自scalaz.
所以这是这类函数的例子
A => Promise[Validation[E, B]]B => Promise[Validation[E, C]]到目前为止,一切都很好,现在如果我要撰写他们,我可以简单的使用的事实Promise呈现flatMap,这样我就可以用了,理解做
for (
x <- f(a);
y <- g(b)
) yield y
Run Code Online (Sandbox Code Playgroud)
好的,我在这里找到了我的问题的捷径,因为我没有Validation在for-comprehension中重用结果.所以,如果我想重用x的g,这里是我怎么能这样做
for (
x <- f(a); // x is a Validation
y <- x.fold(
fail => Promise.pure(x),
ok => g(ok)
)
) yield y
Run Code Online (Sandbox Code Playgroud)
很公平,但这种样板会一遍又一遍地污染我的代码.这里的问题是我有一种两级Monadic结构M[N[_]].
在这个阶段,f°编程中是否有任何结构可以通过轻松跳过secong级别来使用这种结构:
for (
x <- f(a); //x is a B
y <- g(b)
) yield y
Run Code Online (Sandbox Code Playgroud)
现在,下面是我如何实现类似的东西.
我创建了一种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
)
}
Run Code Online (Sandbox Code Playgroud)
这让我可以做这些事情
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
)
)
)
Run Code Online (Sandbox Code Playgroud)
我们可以看到/~~>非常相似flatMap但跳过一个级别.问题在于冗长(这就是Scala中存在"for-comprehension"和Haskell中"do"的原因).
另一点,我/~>是那样的,map但是在第二级(而不是有效类型 - 第三级)工作
所以我的第二个问题是前者的必然结果......我是否正在采用这种结构来实现可持续解决方案?
很抱歉这么久
您在这里寻找的概念是monad 转换器。简而言之,单子变压器补偿了不组合的单子。
\n\n您没有提到您正在使用的 Scalaz 版本,但如果您查看scalaz-7 分支,您会找到ValidationT。这可用于将任何包装F[Validation[E, A]]到 a 中ValidationT[F, E, A],在您的情况下F = Promise。如果您改变f并g返回ValidationT,那么您可以将代码保留为
for {\n x \xe2\x86\x90 f(a)\n y \xe2\x86\x90 g(b)\n} yield y\nRun Code Online (Sandbox Code Playgroud)\n\n这会给你一个ValidationT[Promise, E, B]结果。
| 归档时间: |
|
| 查看次数: |
971 次 |
| 最近记录: |