美文网首页
不是用异常来处理错误(2)

不是用异常来处理错误(2)

作者: 吐思圈 | 来源:发表于2018-02-22 23:21 被阅读0次

    Option不会告诉我们在异常条件下发生了什么错误,它只是给我们一个None,表示没有可用的值。但是有时候我们想知道更多,比如想要一个字符串给出更多的信息或者异常发生时想知道实际错误是什么。这时候我们需要Either数据类型。
    Either数据类型

    sealed trait Either[+E, +A] {
    
    }
    
    case class Left[+E](e: E) extends Either[E, Nothing]
    
    case class Right[+A](a: A) extends Either[Nothing, A]
    

    练习 4.6
    实现Either版的map、flatMap、orElse和map2函数

     def map[B](f: A => B): Either[E, B] = this match {
        case Left(e) => Left(e)
        case Right(a) => Right(f(a))
      }
    
      def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match {
        case Left(e) => Left(e)
        case Right(a) => f(a)
      }
    
      def orElse[EE >: E, B >: A](b: => Either[EE, B]): Either[EE, B] = this match {
        case Left(e) => b
        case _ => this
      }
    
      def map2[EE >: E, B, C](eb: Either[EE, B])(f: (A, B) => C): Either[EE, C] =
        for {
          a <- this
          b <- eb
        } yield f(a, b)
    

    练习 4.7
    对Either实现sequence和traverse,遇到错误返回第一个错误。

      def sequence[E, A](li: List[Either[E, A]]): Either[E, List[A]] = {
        def loop(n: Int, res: Either[E, List[A]]): Either[E, List[A]] = n match {
          case -1 => res
          case _ => li(n) match {
            case Left(e) => Left(e)
            case Right(a) => loop(n - 1, res.map(a :: _))  
          } 
        }
        loop(li.length - 1, Right(Nil))
      }
      
      def traverse[E, A, B](li: List[A])(f: A => Either[E, B]): Either[E, List[B]] =
        sequence(li.map(f))
    

    相关文章

      网友评论

          本文标题:不是用异常来处理错误(2)

          本文链接:https://www.haomeiwen.com/subject/qsaztftx.html