如何调用仅存在于Either中的两种类型之一的方法?

时间:2017-11-09 00:15:28

标签: scala

我有一个类型为[A,B]的对象数组。如果我知道某个特定元素是A还是B,那么如何在其上调用仅存在于2种类型之一上的方法。例如:

predictions = result.get_prediction(out_of_sample_df)
predictions.summary_frame(alpha=0.05)

当我编译此代码时,行

import scala.util.Random

object EitherTest extends App {

    def newObj(x: Int): Either[A,B] = {
        if (x == 0)
            Left(new A())
        else
            Right(new B())
    }

    val random = new Random()
    val randomArray = (0 until 10).map(_ => random.nextInt(2))
    val eitherArray = randomArray.map(newObj) 

    (0 until 10).foreach(x => randomArray(x) match {
        case 0 => eitherArray(x).aMethod()
        case 1 => eitherArray(x).bMethod()
        case _ => println("Error!")
    })

}

class A {
    def aMethod() = println("A")
}

class B {
    def bMethod() = println("B")
}

两者都有错误"值aMethod不是[A,B]"的成员。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

我不知道为什么fold没有得到应有的尊重。它可以如此有用。

eitherArray.foreach(_.fold(_.aMethod(), _.bMethod()))

答案 1 :(得分:1)

好吧,如果你将逻辑推广到另一个方法,你可以做到这一点,并对值进行一些模式匹配,然后检查它是右还是左,这就是它!

object HelloWorld {
    import scala.util.Random
   def main(args: Array[String]) {
        val random = new Random()
        val randomArray = (0 until 10).map(_ => random.nextInt(2))
        val eitherArray = randomArray.map(EitherTest.newObj) 
       (0 until 10).foreach(x => randomArray(x) match {
        case 0 => EitherTest.callmethod(eitherArray(x))
        case 1 => EitherTest.callmethod(eitherArray(x))
        case _ => println("Error!")
        })
       println("Hello, world!")
   }
}


class EitherTest 
object EitherTest {

    def callmethod(ei : Either[A,B]) = {
        ei match {
            case Left(a) => a.aMethod()
            case Right(b) => b.bMethod()
        }
    }

    def newObj(x: Int): Either[A,B] = {
        if (x == 0)
            Left(new A())
        else
            Right(new B())
    }

}

class A {
    def aMethod() = println("A")
}

class B {
    def bMethod() = println("B")
}

将为您打印一个随机示例:

A
B
A
B
A
A
A
B
B
B
Hello, world!

答案 2 :(得分:0)

基本上,使用Either的方式是投影Either.left为您提供左侧类型的投影,Either.right为您提供对。 预测与选项有些相似,因为它们可以为空(如果EitherRight,则left投影为空,反之亦然),您可以使用通常的monadic变换,如mapflatMapforeachgetOrElse等。

您的示例可能如下所示:

 randomArray.foreach { either =>
     either.left.foreach(_.aMethod)
     either.right.foreach(_.bMethod)
 } 

您也可以使用模式匹配,这不太通用,但在这种情况下可能看起来更清晰:

 randomArray.foreach { 
   case Left(a) => a.aMethod
   case Right(b) => b.bMethod
 }