我有一个类型为[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]"的成员。我该如何解决这个问题?
答案 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
为您提供对。
预测与选项有些相似,因为它们可以为空(如果Either
为Right
,则left
投影为空,反之亦然),您可以使用通常的monadic变换,如map
,flatMap
,foreach
,getOrElse
等。
您的示例可能如下所示:
randomArray.foreach { either =>
either.left.foreach(_.aMethod)
either.right.foreach(_.bMethod)
}
您也可以使用模式匹配,这不太通用,但在这种情况下可能看起来更清晰:
randomArray.foreach {
case Left(a) => a.aMethod
case Right(b) => b.bMethod
}