Task.apply 对比 Task.now wrt 功能完整性

Task.apply vs. Task.now wrt Function Totality

鉴于:

$cat build.sbt
scalaVersion := "2.11.8"

libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.5"
libraryDependencies += "org.scalaz" %% "scalaz-concurrent" % "7.2.5"

REPL

scala> import scalaz.concurrent.Task
import scalaz.concurrent.Task

scala> def f(num: BigDecimal, denom: BigDecimal): Task[BigDecimal] = 
           Task { num / denom }
f: (num: BigDecimal, denom: BigDecimal)scalaz.concurrent.Task[BigDecimal]

scala> def g(num: BigDecimal, denom: BigDecimal): Task[BigDecimal] = 
      Task.now { num / denom }
g: (num: BigDecimal, denom: BigDecimal)scalaz.concurrent.Task[BigDecimal]

然后我用 denom0 值调用 fg:

scala> f(1, 0)
res0: scalaz.concurrent.Task[BigDecimal] = scalaz.concurrent.Task@208b1305

scala> g(1, 0)
java.lang.ArithmeticException: Division by zero
  at java.math.BigDecimal.divide(BigDecimal.java:1742)
  at scala.math.BigDecimal.$div(BigDecimal.scala:571)
  at .g(<console>:12)
  ... 42 elided

可以说 f 是全函数,而 g 是偏函数吗?

Task.now 计算其参数,Task.apply 不计算。所以你甚至没有在第二种情况下测试你的假设,这就是你看不到异常的原因。 运行 他们通过 unsafePerformSync 到 运行 Task 里面的代码用 apply 构造。