【问题标题】:Scala Right, Left decomposing difficultiesScala右,左分解困难
【发布时间】:2019-08-10 09:33:01
【问题描述】:

我做了一些scala 练习。我有一个方法:

def getDepartment: (Either[String, Employee]) => Either[String, String] = ???

我需要实现主体。方法参数数据示例:

  1. Right(Employee("Joe", "Finances", Some("Julie")))
  2. Right(Employee("Mary", "IT", None))
  3. Left("找不到员工")

方法应该返回下一个:

  1. 右(“财务”)
  2. 对(“IT”)
  3. Left("找不到员工")

所以我要添加正文:

def getDepartment: (Either[String, Employee]) => Either[String, String] = _ match {
  case _: Left[String, Employee] =>
    println(s"Left: " + _)
    _ // unbound placeholder parameter - compilation error
  case _: Right[String, Employee] =>
    println(s"Right: " + _)
    _ // unbound placeholder parameter - compilation error
  case _ =>
    println(s" " + _)
    _ // unbound placeholder parameter - compilation error
}

我知道我的实现是不正确的,因为编译错误一直存在。看来我没有经验来实施所需的解决方案。

关于方法声明,我发现信息是scala tutorial。但是我没有任何有用的想法如何将_ 映射到所需的类型。可能有人可以帮助修复我的编译错误,提出更好的正文实现方式。

附言

解决方案应在Optional 上实施,不进行错误处理。

附言2

任务取自online resource。练习 4.6 中的第一个任务。

【问题讨论】:

    标签: scala


    【解决方案1】:
    1. 在前两种情况下,您需要为匹配的值命名,而第三种情况没有用(从技术上讲,如果参数是null,它可以匹配,但这是调用方的错误,让他们处理它):

      def getDepartment: (Either[String, Employee]) => Either[String, String] = _ match {
        case left: Left[String, Employee] =>
          println(s"Left: " + left)
          ???
        case right: Right[String, Employee] =>
          println(s"Right: " + right)
          ???
      }
      

      请注意,???s 都需要替换为 Either[String, String] 类型并使用 left/right 的内容。

    2. 但最好使用提取器匹配LeftRight

      def getDepartment: (Either[String, Employee]) => Either[String, String] = _ match {
        case Left(string) =>
          ??? // use string ("contents" of the Left) here
        case Right(employee) =>
          ??? // use employee here
      }
      
    3. _ match { ... } 形式的函数有一个特殊情况,可以让你简单地编写

      def getDepartment: (Either[String, Employee]) => Either[String, String] = {
        case Left(string) =>
          ??? // use string ("contents" of the Left) here
        case Right(employee) =>
          ??? // use employee here
      }
      

    【讨论】:

      【解决方案2】:

      最简单的解决方案是(...在练习资源中也确认了):

      def getDepartment: (Either[String, Employee]) => Either[String, String] = _.map(_.department)
      

      【讨论】:

        【解决方案3】:

        你也可以用 fold 做到这一点。

        def getDepartment: Either[String, Employee] =>  Either[String, String] = _.fold(Left(_), a => Right(a.department))
        

        更新: 和 Either 一起玩,我得出了这个:

        implicit class EitherAsSuffix[T](v: T) { 
          def asRight = Right(v); 
          def asLeft = Left(v);
          // edited again
          def asRight_[L]: Either[L, T] = Right(v)
          def asLeft_[R]: Either[T, R] = Left(v)
          // so that we can, just as a proof of concept, val n = 4.toLeft_[String] 
        }
        

        那么我们可以

        def getDepartment: Either[String, Employee] =>  Either[String, String] = _.fold(_.asLeft, _.department.asRight)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-12-27
          • 2017-10-11
          • 1970-01-01
          • 2014-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多