Похоже, все эти функции определены для класса Либо. Либо может быть в двух «состояниях» - правильном значении и левом, что интерпретировало заднюю ошибку.
Переходим от определения карты. Мы либо параметризированы с типом A. map принимает функцию преобразования типа A в B. Таким образом, функция карты проверяет, является ли значение правильным, тогда она применяет заданную функцию f к правильному значению, обертывает ее правым и возвратным. Если ошибка, то просто верните ошибку.
Right[String, Int](4).map(_*3) // gives Right(12)
Left[String, Int]("error").map(_*3) // gives Left("error")
flatMap похожа на карту, но принимает функция преобразования типа A в любом из правого типа В, поэтому в отличие от карты нам не нужно, чтобы обернуть правильное значение
Right[String, Int](5).flatMap(item => Right(item*3)) //gives Right(15)
Left[String, Int]("error").flatMap(item => Right(item*3)) //gives Left("error")
Как определено, map2 принимает экземпляр Либо b и функцию, преобразуя пару значений типов A и B в третье значение C и возвращая результат, завернутый в Либо. Давайте подробнее рассмотрим, как это реализовано.
this.flatMap(aa => b map (bb => f(aa, bb)))
позволяет переписать его с определением flatMap:
this.match {
case Right(r) => b.map (bb => f(r, bb))
case Left(e) => Left(e)
}
и применить карту:
this.match {
case Right(r) => {
b match {
case Right(br) => Right(f(r, br))
case Left(be) => Left(be)
}
}
case Left(e) => Left(e)
}
Итак, есть три пути:
if right a and right b then apply function(a,b)
if right a and error b then error(b)
if error a then error a
Примеры:
Right(7).map2(Right(4)){case (a,b) => a*b} // gives Right(28)
Right(7).map2(Left[String, Int]("failed")){case (a,b) => a*b} //gives Left("failed")
Left[String, Int]("error").map2(Left[String, Int]("failed")){case (a,b) => a*b} //gives Left("error")
Edit: Внутренняя функция объяснения
Вы должны перейти к функции flatMap с типом:
A => Either[EE, C]
Это означает «взять аргумент типа А и преобразовать его результат типа: либо [EE, C]»
, чтобы вы могли определить:
def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {
def func(aa:A):Either[EE, C] = {
b map (bb => f(aa, bb))
}
this flatMap(func)
}
Я думаю, основная проблема, которую я имею, это синтаксис: 'this flatMap (aa => b map (bb => f (aa, bb)))' что такое aa в этом случае и откуда оно взялось? – jcm
Добавлены некоторые пояснения о внутренней функции – Nyavro
Хм, но я до сих пор не понимаю, как «эта» ссылка передается в func? – jcm