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\n
Run Code Online (Sandbox Code Playgroud)\n\n这会给你一个ValidationT[Promise, E, B]
结果。
归档时间: |
|
查看次数: |
971 次 |
最近记录: |