我的任务是将审计跟踪附加到一堆计算之后用于重构值(即具有业务领域知识的人来解读出错的地方.)当前代码看起来像这样:
def doSomething = f(x) orElse g(x,y,z) orElse h(p,q,r) orElse default
Run Code Online (Sandbox Code Playgroud)
其中每个都返回一个选项.新代码应返回(选项,审计)元组.
我已经实现了它
def doSomething = f(x) match{
case None => g_prime(x,y,z)
case x @ Some(_) => (x, SomeAuditObject)
}
//and taking some liberties with the actual signature...
def g_prime(x,y,z) = g(x,y,z) match{
Run Code Online (Sandbox Code Playgroud)
依此类推,直至"默认".每个函数链接到下一个和下一个,依此类推.我不喜欢它.感觉太必要了.我错过了什么.有一些思考这个问题的方法,我只是没有看到.除了将返回值包装到另一个选项中之外,它是什么?
您可以使用Monads组成留下审计跟踪的转换.您可以在Monad内部进行审核.有关详细信息,请查看此答案.
我试着为你制作一个例子.我不知道如何处理for-comprehension的最后一步,这是一个map并且不提供审计跟踪.如果您不允许使用,map则不能使用for-comprehensions但必须使用普通调用flatMap.
case class WithAudit[A](value: A, audit: String){
def flatMap[B](f: A => WithAudit[B]): WithAudit[B] = {
val bWithAudit = f(value)
WithAudit(bWithAudit.value, audit + ":" + bWithAudit.audit)
}
def map[B](f: A => B): WithAudit[B] = {
WithAudit(f(value), audit + ":applied unknown function")
}
}
def doSomething(in: Option[Int]): WithAudit[Option[Int]] = WithAudit(
in.map(x => x - 23),
"substract 23"
)
def somethingElse(in: Int): WithAudit[String] = WithAudit(
in.toString,
"convert to String"
)
val processed = for(
v <- WithAudit(Some(42), "input Some(42)");
proc <- doSomething(v);
intVal <- WithAudit(proc.getOrElse(0), "if invalid, insert default 0");
asString <- somethingElse(intVal)
) yield asString
println(processed)
Run Code Online (Sandbox Code Playgroud)
输出将是
WithAudit(
19,
input Some(42)
:substract 23
:if invalid, insert default 0
:convert to String
:applied unknown function
)
Run Code Online (Sandbox Code Playgroud)
使用flatMap处理值强制审计的规定.如果你不提供map和限制如何从monad中提取值(如果你这样做可能写一个日志输出),你可以非常安全地假设值的每个转换都会被记录.获得该值后,您将在日志中获得一个条目.
| 归档时间: |
|
| 查看次数: |
1667 次 |
| 最近记录: |