<commit_before>package fpinscala.errorhandling


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

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

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

 def orElse[EE >: E, B >: A](b: => Either[EE, B]): Either[EE, B] = this match {
   case r: Right[A] => r
   case l: Left[E] => b
 }

 def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = for {
   aVal <- this
   bVal <- b
 } yield f(aVal, bVal)
}

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

object Either {
  def mean(xs: IndexedSeq[Double]): Either[String, Double] = 
    if (xs.isEmpty) 
      Left("mean of empty list!")
    else 
      Right(xs.sum / xs.length)

  def safeDiv(x: Int, y: Int): Either[Exception, Int] = 
    try Right(x / y)
    catch { case e: Exception => Left(e) }

  def Try[A](a: => A): Either[Exception, A] =
    try Right(a)
    catch { case e: Exception => Left(e) }

}<commit_msg>4.6 implemented map2 as flatMap map instead of for comprehension just for understanding<commit_after>package fpinscala.errorhandling


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

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

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

 def orElse[EE >: E, B >: A](b: => Either[EE, B]): Either[EE, B] = this match {
   case r: Right[A] => r
   case l: Left[E] => b
 }

def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {
  //for {
//   aVal <- this
//   bVal <- b
// } yield f(aVal, bVal)

  val x: Either[EE, C] = this.flatMap(
  (y: A) =>  b.map(
  (z: B) => f(y,z)))
  x
}

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

object Either {
  def mean(xs: IndexedSeq[Double]): Either[String, Double] = 
    if (xs.isEmpty) 
      Left("mean of empty list!")
    else 
      Right(xs.sum / xs.length)

  def safeDiv(x: Int, y: Int): Either[Exception, Int] = 
    try Right(x / y)
    catch { case e: Exception => Left(e) }

  def Try[A](a: => A): Either[Exception, A] =
    try Right(a)
    catch { case e: Exception => Left(e) }

}
{'fraction_non_alphanumeric': 0.18960468521229867, 'fraction_numerical': 0.0018301610541727673, 'mean_word_length': 3.1598173515981736, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '415932', 'n_tokens_mistral': 1089, 'n_tokens_neox': 1046, 'n_words': 330}