【发布时间】:2021-05-16 10:58:57
【问题描述】:
我正在学习函数式编程并试图理解纯函数。
维基百科说函数是纯的,如果:
- 无副作用
- 将输入映射到输出
纯函数也满足引用透明性,不访问全局变量,也不改变输入变量。
偏函数是纯函数吗?
具有签名类型的函数
def foo(x: Int): Option[Int] = { if(x <= 0) None else Some(x) }
def bar(x: Int): Try[Int] = Try { require(x <= 0); x }
这些函数是纯函数吗?
它们不会将每个输入都映射到正确的输出。
我知道将数据类型声明为 Option/Try 可以让调用者知道它可能会因某些输入而失败。
上面的函数是纯的吗?
【问题讨论】:
-
它们确实将每个输入映射到正确的输出。 Option 和 Try 等效果类型的想法正是以透明引用的方式封装这些东西。
-
def bar(x: Int): Int = { if(x <= 0){ throw new Exception("less than zero")}; x }不纯。但是通过添加Try类型使其变得纯粹?怎么样? -
那是一个不同的问题,这取决于您认为纯和不纯的含义。但是,通常只有学者关心这一点。专业的 FP 开发人员关心 RT 和组合,因为这些属性在我们的代码库中提供了真正的好处,那就是推理的能力。通过添加
Try,您的代码在外部是 RT 并且是可组合的,这很好;有些人(像我自己) 更愿意使用Either并手动引发错误,而不是将其扔到Try的apply中,但这更多是关于代码风格。
标签: scala functional-programming