scala - Scala 中的函数断言

标签 scala functional-programming assert

是否有对返回结果的断言的内置支持?

这样做是非常无用的:

  def addPositive(a: Int, b: Int) = {
    assert(a > 0 && b > 0)
    a + b
  }

我宁愿做类似的事情:
  def addPositive(a: Int, b: Int) = 
    assert(a > 0 && b > 0)(a + b)

通过这种方式,我可以避免断言的命令式方面。 (后者不编译)
有类似的东西吗?

最佳答案

函数式编程将函数视为纯数学函数(理想情况下)。那么数学上说一个函数对某些参数不起作用并且必须爆炸的方法是什么?

Partial Functions

事实证明,Scala 对这个概念有很好的支持: PartialFunction
这是使用部分函数重写代码的方式:

val addPositive: PartialFunction[(Int, Int), Int] = {
  case (a, b) if a > 0 && b > 0 => a + b
}

这有几个好处:

如果你用错误的参数调用它,它会抛出一个 MatchError 异常。
addPositive(-1, 2) => Exception in thread "main" scala.MatchError: (-1,2) (of class scala.Tuple2$mcII$sp)

您实际上可以对函数的域进行采样,以检查某些值是否非常适合作为函数的参数:
addPositive.isDefinedAt(-1, 2) => false

如果您想将该函数应用于某些参数并获得结果或某些指示失败的值,您可以 lift 它以返回 Option
addPositive.lift(-1, 2) => None
addPositive.lift(1, 2) => Some(12)

您可以将其与其他函数组合以在参数无效的情况下提供回退:
val fallback: PartialFunction[(Int, Int), Int] = { case (a, b) => Int.MinValue }
val f = addPositive orElse fallback

f(-1, 2) => -2147483648

或者以自定义方式处理错误:
val raiseError: PartialFunction[(Int, Int), Int] = {
  case (a, b) => throw new IllegalArgumentException(s"Cannot apply addPositive to arguments $a and $b")
}
val g = addPositive orElse raiseError

g(-1, 2) => Exception in thread "main" java.lang.IllegalArgumentException: Cannot apply addPositive to arguments -1 and 2

它适用于标准库:参见 Seq.collectSeq.collectFirst
PartialFunction 也是一个普通的一元函数,所以你也继承了所有的函数操作。

这是一篇非常优雅地解释 Scala 部分函数的文章:

Scala partial functions (without a PhD)

关于scala - Scala 中的函数断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15970145/

相关文章:

java - 在 Java 中如何获得表示 unsigned int 的字节?

scala - 如何在 Scala 中创建只读类成员?

javascript - 在subscribe里面调用subscribe好不好?

Weblogic 和 Struts 2 破坏了 Java 断言

c++ - static_assert 有什么作用,你会用它做什么?

java - 如何创建脚本来运行 jar(在安装 SBT 时)?

scala - Play 模板仅在使用括号调用时有效

haskell - 在 Haskell 中对结构相似类型内的值进行操作

python - 对于学习 Python 函数式编程,推荐哪些好的家庭作业式教程?

unit-testing - 如何在 Rust 中注释空切片的类型?