18

2 つのリモート サービスからデータを集約し、可能な限り迅速に応答を返したいとします。

def loadUser: Future[User]
def loadData: Future[Data]

case class Payload(user: User, data: Data)

これは非同期タスクを順番に実行することを理解しています:

for {
  user <- loadUser
  data <- loadData
} yield Payload(user,data)

これは、非同期タスクが順次チェーンされる前にトリガーされるため、それらを並行して実行します。

val userF = loadUser
val dataF = loadData
for {
  user <- userF 
  data <- dataF
} yield Payload(user,data)

しかし、その違いは私には少し暗すぎて、最初は気付かない人もいるかもしれません。


Applicatives も仕事を解決します

(loadUser |@| loadData) { Payload(_,_) }

並列非同期計算を実行するために、アプリケーションとモナドの間で何を使用したいか教えてもらえますか? 各アプローチの長所と短所は何ですか?

4

1 に答える 1

15

すべてのコメントが有用なリソースにリンクしているため、私は自分の質問に答えています。

トラヴィス・ブラウンは素晴らしい答えを持っていました:

仕事を成し遂げる最も強力でない抽象化を使用することは、堅実な開発慣行です。原則として、これにより、他の方法では不可能な最適化が可能になる可能性がありますが、さらに重要なことは、記述したコードがより再利用しやすくなるということです。

また、彼は興味深い事実を指摘しています。

Haskell と Scala の両方が現在、アプリカティブ ファンクターで作業するよりも (構文的になど) モナドで作業する方がはるかに便利になっているのは残念です。

Kolmar は、2 つの先物を圧縮することが可能であると指摘しました。

for ((user, data) <- loadUser zip loadData) yield Payload(user, data)

ただし、2 つ以上の先物を圧縮するのはあまりエレガントではないようです。

Applicative functor がこの仕事に最も適しているように見えますが、Scala の標準ライブラリはモナドと比較してそれらを使用することをあまり奨励しておらず、Scalaz や Cats のような追加のライブラリが必要です。

于 2016-02-02T09:49:17.677 に答える