2015-12-02 5 views
0

У меня есть следующий SCALA код (от FP В Scala книге):Что происходит под обложками в этом коде Scala?

import scala.{Option => _, Either => _, Left => _, Right => _, _} // hide std library `Option` and `Either`, since we are writing our own in this chapter 

case class Left[+E](get: E) extends Either[E,Nothing] 
case class Right[+A](get: A) extends Either[Nothing,A] 

sealed trait Either[+E,+A] { 
def map[B](f: A => B): Either[E, B] = this match { 
    case Right(r) => Right(f(r)) 
    case Left(e) => Left(e) 
} 

def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match { 
    case Right(r) => f(r) 
    case Left(e) => Left(e) 
} 

def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = { 
    this flatMap(aa => b map (bb => f(aa, bb))) 
} 

} 

Я хотел бы знать, что происходит, когда я звоню map2 так:

val b = fpinscala.errorhandling.Right(2) 
val a = fpinscala.errorhandling.Right("right") 
val f = (a: String, b:Int) => a + b 
a.map2(b)(f) 

Как делает Scala знать, использовать замену this (т.е. a) в aa в этой строке кода: this flatMap(aa => b map (bb => f(aa, bb))) в функции map2?

+0

Возможный дубликат [Как прочесть этот flatMap-код?] (Http://stackoverflow.com/questions/34033746/how-to-read-this-flatmap-code) –

ответ

0

@jcm, увидеть, если это имеет смысл.

a.map2(b)(f) 

Мы вызов map2 метода a объекта. Внутри метода код a теперь ссылается как this.

this flatMap(aa => b map (bb => f(aa, bb))) 

Теперь мы вызываем flatMap метод this объекта (который до сих пор a).

Что делает flatMap принять в качестве аргумента?Он принимает функцию, функцию, которая принимает аргумент (определенного типа, который мы будем называть «А») и возвращает Either. Таким образом, это означает, что все между круглыми скобками является этой функцией. Эта функция не имеет имени (т. Е. Нет def), поэтому ее часто называют анонимной функцией.

Эта функция принимает аргумент. Этот код aa => идентифицирует аргумент, чтобы впоследствии его можно было отнести к функции. «aa» - просто произвольное имя. Мы могли бы использовать «thisthat» или «xyz».

Откуда берется значение, которое содержит aa? Он выходит из this. Рассмотрим следующий код.

List(4,7,9).map(x => 42 - x) 

В этом случае map вызывает анонимную функцию три раза, один раз для каждого значения из списка. x получает новое значение (сначала 4, затем 7, затем 9) каждый раз при вызове функции.

Если все это имеет смысл, примените ту же логику к b map (bb => .....), и вы почти дома!

0

Как Scala знать, чтобы использовать заменитель this (т.е. a) в aa

aa не заменяется this. aa заменяется на строку "right".

Замена осуществляется flatMap здесь:

case Right(r) => f(r) 

flatMap проверяет, является ли этот экземпляр Either является Right или Left. Если это Right, он передает его содержимое (строка "right") в функцию f (aa => b map (bb => f(aa, bb))).

0

Как Scala знать, чтобы использовать заменитель этого (т.е.) в аа в эта строка кода: это flatMap (аа => Ь отображение (бб => е (аа, бб))) в карта2 функция?

Это не так. То, что происходит здесь, заключается в следующем:

  1. Замыкание строится, который принимает Either[EE,B], называет его aa и вычисляет b map (bb => f(aa, bb). b и f взяты из родительской области.
  2. this.flatMap вызывается с учетом функции как параметра.

Подробнее о Scala CLOSURES :-)

Смежные вопросы