2

いくつかのコンポーネントで構成されるアプリケーションを開発しているとします。次に、アプリケーションのステータスを返す関数を書きたいと思います

ケース クラス ステータス(...)
def status[A](a:A):Status = {...} // A - ステータスの計算に使用されるデータ

この関数はおそらく、コンポーネントのステータスを返す他の関数を呼び出す必要があり、それらの各コンポーネント関数は、サブコンポーネントのステータスを返す他の関数などを呼び出す必要があります。

Scala でそのような関数のライブラリをどのように設計しますか? これらの関数は のように見えますmonadか?

4

1 に答える 1

3

ここには 2 つの明らかなアプローチがあります。1 つ目は、パターン マッチングを使用してデータ構造を分解します。

// Just use Boolean for status
type Status = Boolean

trait Statusable
class class A(isOk : Boolean) extends Statusable
class class B(a : A) extends Statusable
class class C(first : B, second : B) extends Statusable

def status(a : Statusable) : Status = a match {
  case a : A => a.isOk
  case B(a) => status(b.a)
  case C(first, second) => status(first) && status(second)
}

status(C(B(A(true)), B(A(false))))
// returns false

status(C(B(A(true)), B(A(true))))
// returns true

さて、あなたはその特性 'Stat' が少しひどいように見えると考えているかもしれません。また、データ クラスが共通のベースから派生することを強制したくないかもしれません。この場合、型クラスが役に立ちます。

trait HasStatus[A] { def getStatus(a : A) : Status }
object HasStatus {

  def status[A : HasStatus](a : A) = implicitly[HasStatus[A]].getStatus(a)

  implicit object AHasStatus extends HasStatus[A] {
    def getStatus(a : A) = a.isOk
  }
  implicit object BHasStatus extends HasStatus[B] {
    def getStatus(b : B) = status(b.a)
  }
  implicit object CHasStatus extends HasStatus[C] {
    def getStatus(c : C) = status(c.first) && status(c.second)
  }
}
import HasStatus._
status(C(B(A(true)), B(A(false))))
//returns false
于 2012-05-29T16:00:01.347 に答える