今日は、私は次のような問題に出くわした警備員: 私はいくつかのパターンマッチングを簡素化はこのように見て、起こっていた:Scalaの非同期とのパターンマッチング(または任意のモナド)は
object Sync {
sealed trait MatchType
case object BigType extends MatchType
case object SmallType extends MatchType
case object EvenType extends MatchType
case object UnknownType extends MatchType
def syncPatternMatch(i: Int): MatchType = i match {
case _ if i > 100 => BigType
case _ if i < 3 => SmallType
case _ if i % 2 == 0 => EvenType
case _ => UnknownType
}
}
を今、残念ながら、私は考え出しました私のガード/エクストラクタはFuture[Boolean]
になるでしょう。結果を得るために外部Webサービスを呼び出すとします。 明らかに、未来(またはモナド)でガードまたは抽出パターンを使用することはできません。
ここで、各条件を非同期でチェックしたいが、最初の成功した条件を打破したい。
基本的に私は正常なモナドの流れの反対を望んでいます - 最初の成功で止まることを意味します。
私の実装はうまくいくようですが、もっと簡単な方法があるかどうか、この場合はどのようなパターンを使用するかを調べたいと思っています。
私の例は非常に簡単な例であることを覚えておいてください。 the cats one LIKE '場合モナド'
import cats.data.EitherT
import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Async {
sealed trait MatchType
case object BigType extends MatchType
case object SmallType extends MatchType
case object EvenType extends MatchType
case object UnknownType extends MatchType
type Match[B] = EitherT[Future, MatchType, B]
def isBigEnough(i: Int): Match[Unit] = Future(if(i > 100) Left(BigType) else Right(()))
def isVerySmall(i: Int): Match[Unit] = Future(if(i < 3) Left(SmallType) else Right(()))
def isEven(i: Int): Match[Unit] = Future(if(i % 2 == 0) Left(EvenType) else Right(()))
def otherwise: Match[MatchType] = Future.successful(Right(UnknownType))
implicit def liftFutureEither[A, B](f: Future[Either[A, B]]): EitherT[Future, A, B] = EitherT(f)
implicit def extractFutureEither[A, B](e: EitherT[Future, A, B]): Future[Either[A, B]] = e.value
def asyncPatternMatch(i: Int): Match[MatchType] = for {
_ <- isBigEnough(i)
_ <- isVerySmall(i)
_ <- isEven(i)
default <- otherwise
} yield default
asyncPatternMatch(10).foreach(either => println(either.fold(identity, identity)))
// EvenType
}
は(ところで。それは2.12スカラ座である)
私は提案のために幸せになる:)
私はあなたがあまりにも多くを考慮したと思います。 'def asyncPatternMatch(i:Future [Int]):Match [MatchType] = i.map(syncPatternMatch)'を試してください。 –
私のガードは非同期ですが、 'isBigEnough'が結果を得るために外部APIを呼び出していると想像してください。 入力としての 'Future [Int]'がここで私をどのように助けてくれるのか、実際は分かりません。 – rincewind