如何在Scala中设计一个简单的监控库?

时间:2012-05-29 13:16:38

标签: scala functional-programming monads software-design

假设,我正在开发一个由几个组件组成的应用程序。现在我想写一个函数来返回应用程序状态

case class Status(...)
def status[A](a:A):Status = {...} // A - data used to calculate the status

这个函数可能应该调用其他函数,这些函数返回组件的状态,每个组件函数调用其他函数,返回子组件的状态等等,等等

您如何在Scala中设计这样的函数库?这些功能看起来像monad吗?

1 个答案:

答案 0 :(得分:3)

这里有两种明显的方法。第一种方法使用模式匹配来分解数据结构:

// 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