2016-04-19 4 views
1

私はいくつかのイベントクラスを定義し、インターフェイス記述言語で外部的に生成しました。これらのタイプの定義は、私だけの単純な生成されたケースクラスへのアクセス権を持っている私のコントロール - を超えて:サブタイプの異種リストを含むスカラー暗黙のクラス

sealed trait Event 
case class EventOpen(msg: String) extends Event 
case class EventClose(msg: String) extends Event 

これらのイベントのリストを考えると、私は単一の値にそれらを折るする必要があります。目的は、特定のコンテキストに必要に応じて使用できる折り畳み関数のライブラリを構築することです。たとえば、ストリームが開いているか閉じているかを判断する。イベントのリストがかなり長いため、折りたたみ関数内での巨大なパターンの一致を避けるため、必要に応じて各イベントに機能を追加する暗黙のクラスを使用し、必要に応じてインポートするようにパッケージ化していきたいと考えていました:

sealed trait Status 
case object Open extends Status 
case object Closed extends Status 
case object Unknown extends Status 

// Do nothing unless a specific EventOp is defined. 
implicit class EventNoOp(event: Event) { 
    def accumulate(status: Status): Status = status 
} 

implicit class EventOpenOp(event: EventOpen) { 
    def accumulate(status: Status): Status = Open 
} 

implicit class EventCloseOp(event: EventClose) { 
    def accumulate(status: Status): Status = Closed 
} 

val initial: Status = Unknown 
List(EventOpen("yeeha"), EventClose("adios")).foldLeft(initial)((status, event) => event.accumulate(status)) // => Unknown 

問題は、特定のタイプのイベントが折りたたみで失われるため、EventNoOpだけが呼び出され、「閉鎖」ではなく「不明」になります。明示的に折りたたみ関数内でパターンマッチングは、問題を解決し、それは最初の場所でのアプローチの目的に反し:

val initial: Status = Unknown 
List(EventOpen("yeeha"), EventClose("adios")).foldLeft(initial)((status, event) => { 
    event match { 
    case e: EventOpen => e.accumulate(status) 
    case e: EventClose => e.accumulate(status) 
    } 
}) 

は、各イベントの明示的なパターンマッチを回避するための方法はありますか?

答えて

4

各イベントで明示的なパターンマッチングを避ける方法はありますか?私は暗黙を使用して、あなたのソリューションは、実際にパターンマッチングを使用するよりもより定型につながると思います

...これは、暗黙的なベースのソリューションよりも、私にははるかに直感的なようだ:

def accumulateStatus(status: Status, event: Event): Status = event match { 
    case EventOpen(_) => Open 
    case EventClose(_) => Closed 
    case _    => status 
} 

val initial: Status = Unknown 
List(EventOpen("yeeha"), EventClose("adios")).foldLeft(initial)(accumulateStatus) 

することができますので、 Eventのクラスを直接変更しないと、パターンマッチングに悩まされます(あるいは、実行時の型の比較/リフレクションでさらに厄介なことをする)。

関連する問題