我目前正在進行關於函數式編程的演示,並且遇到了以下問題。斯卡拉的嘗試是否透明?
函數式編程旨在將'what'與'how',或者更確切地說是從其解釋中的計算聲明中分離出來。這就是爲什麼這種範例的主要焦點之一是使用可組合的數據結構來表示計算,而不做任何關於它們如何執行的假設。例如:
// Represents a computation that may fail
case class Unsafe[A,B](run: A => B)
// ...
val readIntFromFile: Unsafe[String, Int] = Unsafe { filePath => /* ... */ }
interpret(readIntFromFile)
// Interpreter
def interpret(u: Unsafe[String, Int]): Unit = {
try {
u.run("path/to/file")
} catch {
case e => /* ... */
}
}
這似乎是有道理的,因爲副作用應該計算的執行過程中,而不是其聲明中只執行。問題是,在Scala中,因爲它似乎,許多數據結構打破了這個規則:
object Try {
/** Constructs a `Try` using the by-name parameter. This
* method will ensure any non-fatal exception is caught and a
* `Failure` object is returned.
*/
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
}
同爲Futures
:
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
*
* The result becomes available once the asynchronous computation is completed.
*
* @tparam T the type of the result
* @param body the asynchronous computation
* @param executor the execution context on which the future is run
* @return the `Future` holding the result of the computation
*/
def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] = impl.Future(body)
所以,我現在想知道,是Try
和Future
真透明的?如果不是,那麼如何處理錯誤情況而不依賴於Success
和Failure
?
非常酷的答案。我從來沒有想過像這樣嘗試。 –
我還會補充一點:我覺得大多數時候,'Try'是錯誤的抽象,而'Either'和'IO'更準確。 –
@FrancisToth我認爲這或多或少是正確的。 '嘗試'基本上就像聲明「拋出異常」。這比根本不記錄錯誤情況要好,但除此之外不會給你任何額外的信息,而且不像'Either'它要求你的錯誤情況是一個例外。另一方面,「IO/Task」處理完全不同的問題。 – puhlen