- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经使用免费的 monad 为 ETL 过程实现了一种简单的语言。使用 List
时作为数据获取和存储的输入和输出,一切正常。但是我正在使用异步库并使用 Future[List]
常见的导入和定义
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import cats.free.Free
import cats.free.Free._
sealed trait Ops[A]
type OpsF[A] = Free[Ops, A]
List
合作
case class Fetch(offset: Int, amount: Int) extends Ops[List[Record]]
case class Store(recs: List[Record]) extends Ops[List[Response]]
def fetch(offset: Int, amount: Int): OpsF[List[Record]] =
liftF[Ops, List[Record]](Fetch(offset, amount))
def store(recs: List[Record]): OpsF[List[Response]] =
liftF[Ops, List[Response]](Store(recs))
def simpleEtl(offset: Int, amount: Int): Free[Ops, List[Response]] =
fetch(offset, amount).flatMap(r => store(r))
Future[List]
case class Fetch(offset: Int, amount: Int) extends Ops[Future[List[Record]]]
case class Store(recs: List[Record]) extends Ops[Future[List[Response]]]
def fetch(offset: Int, amount: Int): OpsF[Future[List[Record]]] =
liftF[Ops, Future[List[Record]]](Fetch(offset, amount))
def store(recs: List[Record]): OpsF[Future[List[Response]]] =
liftF[Ops, Future[List[Response]]](Store(recs))
// explicit types in case I am misunderstanding more than I think
def simpleEtl(offset: Int, amount: Int): Free[Ops, Future[List[Response]]] =
fetch(offset, amount).flatMap { rf: Future[List[Record]] =>
val getResponses: OpsF[Future[List[Response]]] = rf map { r: List[Record] =>
store(r)
}
getResponses
}
flatMap
返回的类型/
map
错了 - 我没有得到
OpsF[Future]
但是一个
Future[OpsF]
Error:(34, 60) type mismatch;
found : scala.concurrent.Future[OpsF[scala.concurrent.Future[List[Response]]]]
(which expands to) scala.concurrent.Future[cats.free.Free[Ops,scala.concurrent.Future[List[String]]]]
required: OpsF[scala.concurrent.Future[List[Response]]]
(which expands to) cats.free.Free[Ops,scala.concurrent.Future[List[String]]]
val getResponses: OpsF[Future[List[Response]]] = rf map { r: List[Record] =>
store
接受
Future[List[Record]]
并让解释器映射到
Future
,但感觉很笨拙。
List
- 例如
Option
也会很有用。
最佳答案
抽象数据类型Ops
定义一个代数来获取和存储多个 Record
s。它描述了两个操作,但这也是代数应该做的唯一事情。操作是如何实际执行的,对 Fetch
完全不重要。和 Store
,您期望的唯一有用的东西分别是 List[Record]
和 List[Response]
.
通过将预期结果类型设为 Fetch
和 Store
一个 Future[List[Record]]]
,你限制了如何解释这个代数的可能性。也许在您的测试中,您不想异步连接到 Web 服务或数据库,而只想使用 Map[Int, Result]
进行测试。或 Vector[Result]
,但现在您需要返回 Future
这使得测试比它们可能的更复杂。
但是说你不需要ETL[Future[List[Record]]]
不能解决您的问题:您正在使用异步库,您可能想要返回一些 Future
.
从您的第一个实现开始:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import cats.implicits._
import cats.free.Free
type Record = String
type Response = String
sealed trait EtlOp[T]
case class Fetch(offset: Int, amount: Int) extends EtlOp[List[Record]]
case class Store(recs: List[Record]) extends EtlOp[List[Response]]
type ETL[A] = Free[EtlOp, A]
def fetch(offset: Int, amount: Int): ETL[List[Record]] =
Free.liftF(Fetch(offset, amount))
def store(recs: List[Record]): ETL[List[Response]] =
Free.liftF(Store(recs))
def fetchStore(offset: Int, amount: Int): ETL[List[Response]] =
fetch(offset, amount).flatMap(store)
Future
年代?这就是我们口译员的工作:
import cats.~>
val interpretFutureDumb: EtlOp ~> Future = new (EtlOp ~> Future) {
def apply[A](op: EtlOp[A]): Future[A] = op match {
case Store(records) =>
Future.successful(records.map(rec => s"Resp($rec)"))
// store in DB, send to webservice, ...
case Fetch(offset, amount) =>
Future.successful(List.fill(amount)(offset.toString))
// get from DB, from webservice, ...
}
}
Future.successful(...)
)我们可以得到我们的
Future[List[Response]]
:
val responses: Future[List[Response]] =
fetchStore(1, 5).foldMap(interpretFutureDumb)
val records: Future[List[Record]] =
fetch(2, 4).foldMap(interpretFutureDumb)
responses.foreach(println)
// List(Resp(1), Resp(1), Resp(1), Resp(1), Resp(1))
records.foreach(println)
// List(2, 2, 2, 2)
Future
的不同解释器。 :
import scala.collection.mutable.ListBuffer
import cats.Id
val interpretSync: EtlOp ~> Id = new (EtlOp ~> Id) {
val records: ListBuffer[Record] = ListBuffer()
def apply[A](op: EtlOp[A]): Id[A] = op match {
case Store(recs) =>
records ++= recs
records.toList
case Fetch(offset, amount) =>
records.drop(offset).take(amount).toList
}
}
val etlResponse: ETL[List[Response]] =
for {
_ <- store(List("a", "b", "c", "d"))
records <- fetch(1, 2)
resp <- store(records)
} yield resp
val responses2: List[Response] = etlResponse.foldMap(interpretSync)
// List(a, b, c, d, b, c)
关于scala - 如何将 free monad 与 Future[M[_]] 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37783939/
我正在通过这个示例https://www.rusoto.org/futures.html学习Rust和Rusoto 而且我发现许多代码已经过时了。所以我改变了这样的代码: use rusoto_cor
这是一个理论问题。我有一个服务可以调用来完成工作,但该服务可能无法完成所有工作,因此我需要调用第二个服务来完成它。 我想知道是否有办法在没有 Await.result 的情况下做类似的事情map 函数
这个问题是关于如何阅读 Rust 文档并提高我对 Rust 的理解,从而了解如何解决这个特定的编译器错误。 我读过 tokio docs并试验了许多 examples .在编写自己的代码时,我经常遇到
我有一个使用分页的 HTTP api,我想将它包装到一个通用的 Rust 流中,以便所有端点都可以使用相同的接口(interface),这样我就可以使用 Stream 附带的特征函数特征。 我收到了这
我正在查看 AKKA 的 Java Futures API,我看到了很多处理同一类型的多个 future 的方法,但我没有看到任何处理不同类型的 future 的方法。我猜我让事情变得更加复杂了。 无
环境:Akka 2.1,scala 版本 2.10.M6,JDK 1.7,u5 现在是我的问题: 我有: future1 = Futures.future(new Callable>(){...});
我有一些代码可以将请求提交给另一个线程,该线程可能会也可能不会将该请求提交给另一个线程。这会产生 Future> 的返回类型.是否有一些非令人发指的方法可以立即将其变成 Future等待整个 futu
如果我有以下代码: Future a = new Future(() { print('a'); return 1; }); Future b = new Future.error('Error!')
我一直试图简化我在 Scala 中做 future 的方式。我有一次收到了 Future[Option[Future[Option[Boolean]]但我在下面进一步简化了它。有没有更好的方法来简化这
Scala 中从 Future[Option[Future[Int]]] 转换的最干净的方法是什么?至 Future[Option[Int]] ?甚至有可能吗? 最佳答案 有两个嵌套Future s
使用下面的示例,future2 如何在 future1 完成后使用 future1 的结果(不阻塞 future3 从被提交)? from concurrent.futures import Proc
这两个类代表了并发编程的优秀抽象,因此它们不支持相同的 API 有点令人不安。 具体根据docs : asyncio.Future is almost compatible with concurre
我正在尝试使用 wasm_bindgen 实现 API 类使用异步调用。 #![allow(non_snake_case)] use std::future::Future; use serde::{
这个问题在这里已经有了答案: Futures / Success race (3 个回答) 去年关闭。 所有的 future 最终可能会成功(有些可能会失败),但我们希望第一个成功。并希望将这一结果表
我在练习asyncio在编写多线程代码多年之后。 注意到一些我觉得很奇怪的东西。都在 asyncio在 concurrent有一个Future目的。 from asyncio import Futur
如何将Future[Option[Future[Option[X]]]]转换为Future[Option[X]]? 如果它是 TraversableOnce 而不是 Option 我会使用 Futur
我正在尝试同时发送 HTTP 请求。为此,我使用 concurrent.futures 这是简单的代码: import requests from concurrent import futures
我们在 vertx 中使用 Futures 的例子如下: Future fetchVehicle = getUserBookedVehicle(routingContext, client);
下面的函数,取自 here : fn connection_for( &self, pool_key: PoolKey, ) -> impl Future>, ClientError>
我正在围绕Java库编写一个小的Scala包装器。 Java库有一个对象QueryExecutor,它公开了2种方法: execute(query):结果 asyncExecute(query):Li
我是一名优秀的程序员,十分优秀!