F#和Scala都充当一种混合语言,通常用于将传统的面向对象代码的单词桥接到功能代码。
一个更属于OO世界的概念是个例外,而在许多情况下,功能世界更喜欢Option类型。为了包装依赖于异常的现有库代码并使之更具功能性,我因此想“提升”抛出异常的代码,以代替返回一个选项类型。
在Scala中,有一个不错的库函数可以“全部捕获”并转换为option。可以这样使用:
import scala.util.control.Exception._
val functionalVersion = allCatch opt myFunction
Run Code Online (Sandbox Code Playgroud)
请参见在Scala中,是否存在用于将异常转换为Options的预先存在的库函数?
现在,我要使用F#,但我有相同的要求,但是似乎无法为此找到一个现有的实用程序功能,而且自己也很难实现。
我可以为单元功能(也称为动作)创建这样的包装器
let catchAll f = try Some (f()) with | _ -> None
Run Code Online (Sandbox Code Playgroud)
但是这里的问题是我不想先将所有抛出代码的代码包装到一个动作中。
例如,我想包装数组索引运算符,以便它不会抛出。
// Wrap out-of-bounds exception with option type
let maybeGetIndex (array: int[]) (index: int) = catchAll (fun () -> array.[index])
maybeGetIndex [| 1; 2; 3 |] 10 // -> None
Run Code Online (Sandbox Code Playgroud)
但是,如果可以简单地编写,那就更好了。
(catchAll a.[index])
Run Code Online (Sandbox Code Playgroud)
即在计算之前将catchAll应用于整个表达式。(Scala可以通过F#似乎缺少的按名字调用参数来实现此目的)
所以这个问题是双重的: