문제

나는 = 이해를 위한 스칼라(섹션에 지정된 대로) 6.19 SLS의) 다음과 같습니다.

옵션

어떤 기능이 있다고 가정 해 봅시다 String => Option[Int]:

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)

즉, 임베디드 생성기는 map 일련의 flatMap 전화.여태까지는 그런대로 잘됐다.

어느쪽이든.오른쪽투영

내가 실제로 하고 싶은 일은: 이전 예제와 유사한 for-comprehension을 사용합니다. Either 모나드.

그러나 비슷한 체인에서 사용하지만 이번에는 Either.RightProjection 모나드/펑터, 작동하지 않습니다:

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
                ^

문제는 오른쪽 투영이 인수로 기대하는 기능과 관련이 있습니다. flatMap 방법(예:그것은 기대한다 R => Either[L, R]).하지만 전화하지 않도록 수정 right 두 번째 생성기에서는 여전히 컴파일되지 않습니다.

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)
                            ^

엄청난 혼란

하지만 이제 나는 두 배로 혼란스러워졌습니다.다음은 잘 작동합니다.

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 }
                                                                                             ^

나는 이것이 동등하다고 생각했다

  • 무슨 일이야?
  • 어떻게 삽입할 수 있나요? = 전체에 대한 이해를 위한 생성기 Either?
도움이 되었습니까?

해결책

삽입할 수 없다는 사실 = 이해를 위해 다음과 관련이 있습니다. 이 문제 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 }}

따라서 귀하의 경우에는 y(b) 결과 유형이 있음 Either 없는 것 map 한정된.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top