質問

把握のための=を使用することはできます(セクション SLS 6.19

オプション

いくつかの関数を持っているとします.GenagodicetagCode:

scala> def intOpt(s: String) = try { Some(s.toInt) } catch { case _ => None }
intOpt: (s: String)Option[Int]
.

それから私はそれを使うことができます

scala> for {
   |     str <- Option("1")
   |     i <- intOpt(str)
   |     val j = i + 10    //Note use of = in generator
   |   }
   |   yield j
res18: Option[Int] = Some(11)
.

これは本質的に:

と同等であることが私の理解でした。
scala> Option("1") flatMap { str => intOpt(str) } map { i => i + 10 } map { j => j }
res19: Option[Int] = Some(11)
.

すなわち、埋め込み発電機は、String => Option[Int]呼び出しのシーケンスにmapを注入する方法でした。これまでのところとても良い。

どちらか。rightprojection

実際に何をしたいのか flatMap monad を使用している前の例として、概要と同様の理解のために使用します。

しかし、私たちが同様のチェーンでそれを使うならば、今回はEither Monad / Functorを使用していますが、それはうまくいきません:

scala> def intEither(s: String): Either[Throwable, Int] = 
  |      try { Right(s.toInt) } catch { case x => Left(x) }
intEither: (s: String)Either[Throwable,Int]
.

使用:

scala> for {
 | str <- Option("1").toRight(new Throwable()).right
 | i <- intEither(str).right //note the "right" projection is used
 | val j = i + 10
 | }
 | yield j
<console>:17: error: value map is not a member of Product with Serializable with Either[java.lang.Throwable,(Int, Int)]
              i <- intEither(str).right
                ^
.

問題には、右の投影がそのEither.RightProjectionメソッドの引数として予想される関数と関係がある(すなわち、それはflatMapを期待する)。しかし、2番目の発電機でR => Either[L, R]を呼び出さないように変更すると、まだコンパイルされません。

scala>  for {
 |        str <- Option("1").toRight(new Throwable()).right
 |        i <- intEither(str) // no "right" projection
 |          val j = i + 10
 |      }
 |      yield j
<console>:17: error: value map is not a member of Either[Throwable,Int]
              i <- intEither(str)
                            ^
.

Mega混入

しかし今、私は二重に混同します。以下は大丈夫です:

scala> for {
 |       x <- Right[Throwable, String]("1").right
 |       y <- Right[Throwable, String](x).right //note the "right" here
 |     } yield y.toInt
res39: Either[Throwable,Int] = Right(1)
.

しかしこれは:

scala> Right[Throwable, String]("1").right flatMap { x => Right[Throwable, String](x).right } map { y => y.toInt }
<console>:14: error: type mismatch;
 found   : Either.RightProjection[Throwable,String]
 required: Either[?,?]
              Right[Throwable, String]("1").right flatMap { x => Right[Throwable, String](x).right } map { y => y.toInt }
                                                                                             ^
.

私はこれらが等価だと思った

  • 何が起こっているの?
  • rightを介して=ジェネレータを埋め込む方法は?
役に立ちましたか?

解決

把握用=を埋め込むことができないという事実は、この問題 Jason Zauggによって報告されました。解決策は、右バイアスEither(またはそれに新しいデータ型イソフォルフィックを作成する)に対象です。

あなたのメガの混乱のために、あなたは砂糖を誤って拡大しました。

の脱がれている
for {
  b <- x(a)
  c <- y(b)
} yield z(c)
.

です
x(a) flatMap { b =>
 y(b) map { c =>
  z(c) }} 
.

ではなく

x(a) flatMap { b => y(b)} map { c => z(c) }
.

それゆえあなたはこれをしたはずです:

scala> Right[Throwable, String]("1").right flatMap { x => Right[Throwable, String](x).right map { y => y.toInt } }
res49: Either[Throwable,Int] = Right(1)
.

デスガルのより楽しい( `j= i + 10の問題)

for {
  b <- x(a)
  c <- y(b)
  x1 = f1(b)
  x2 = f2(b, x1)
  ...
  xn = fn(.....)
  d <- z(c, xn)
} yield w(d)
.

に枯れます
x(a) flatMap { b =>
  y(b) map { c =>
    x1 = ..
    ...
    xn = ..
    (c, x1, .., xn) 
  } flatMap { (_c1, _x1, .., _xn) =>
    z(_c1, _xn) map w }}
.

SOの場合、y(b)には、Eitherが定義されていない結果型mapがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top