2017-11-09 9 views
4

私はタイプが[A、B]のオブジェクトの配列を持っています。特定の要素がAかBのどちらであるかを知っているなら、どのように2つの型のうちの1つにしか存在しないメソッドを呼び出すことができます。例えば:私はこのコードをコンパイルするときいずれかの2つのタイプのいずれかにしか存在しないメソッドを呼び出すにはどうすればよいですか?

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") 
} 

、ライン

case 0 => eitherArray(x).aMethod() 
case 1 => eitherArray(x).bMethod() 

両方がエラー "値aMethodのいずれか[A、B]のメンバーではない" を有します。これをどうすれば解決できますか?

+0

'bothArray(x).left.foreach(_。aMethod)' ... – Dima

答えて

1

ロジックを別の方法でエクストラクトして、値Eitherのパターンマッチングを行い、それが右か左かをチェックすれば、それは可能です!

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") 
} 

は1ランダムたとえば、あなたのために印刷されます:

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

は基本的に、あなたがEitherで行う方法が投影です:Either.leftはあなたの左のタイプの投影を与え、Either.rightができますあなたは右のものです。 投影は空にできる点でオプションと多少似ています(EitherRightの場合left投影が空で、その逆の場合)mapflatMapなどの通常のモナディック変換を使用することができます。 foreachgetOrElseなど

あなたの例では、次のようになります。

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

また、代わりに、パターンマッチングを使用することができ、それはおそらく、この場合、ビット明確に見え、あまり一般的ですが、:

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

なぜfoldが尊敬を受けていないのかわかりません。 なので、が便利です。

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

私はフォールドが大好きです。 ALL TEH THINGZをフォールド! –

関連する問題