gpt4 book ai didi

f# - 无点函数中的异常处理

转载 作者:行者123 更新时间:2023-12-01 08:12:11 25 4
gpt4 key购买 nike

我遇到了一个看似微不足道的问题:如果函数以无点方式编写,我将无法处理异常。

考虑这两个函数:

let divide1 x y =
try
x / y
with
| :? System.DivideByZeroException -> 42

let divide2 =
try
(/)
with
| :? System.DivideByZeroException -> fun _ _ -> 42

let x1 = divide1 5 0 // works fine
let x2 = divide2 5 0 // doesn't handle an exception

尽管这两个函数看似相同,但它们具有不同的类型:
val divide1: int -> int -> int
val divide2: (int -> int -> int)

显然, divide2甚至不尝试处理异常。它只是返回一个运算符。

我该怎么做才能使 divide2以适当的方式处理异常(除非特别声明其参数)?

最佳答案

这就是我发现无点样式有问题的原因之一。这使得使用像 try .. with 这样的标准语言结构变得困难。 (或标准循环和其他 F# 功能),您需要将它们替换为自定义组合器。在这种情况下,您可以定义组合子 tryWith2在异常处理程序中包装了一个双参数函数:

let tryWith2 f h a b = 
try f a b // Call the function with two arguments
with e ->
// Try running the error handler with the exception
match h e with
| Some g -> g a b // Error handler provided another function
| _ -> reraise() // Error was not handled - reraise

然后你可以用这样的无点风格编写函数(错误处理仍然不是无点的,但我不想让它太傻:-))
let divide2 =
tryWith2 (/) (function
| :? System.DivideByZeroException -> Some(fun _ _ -> 42)
| _ -> None)

let x1 = divide2 5 0 // returns 42
let x2 = divide2 5 1 // returns 5

当然,point free 风格很有用,即使在 F# 中也是如此。例如,在编写 DSL 时,这是编写声明式规范的好方法(因为原语使用更高级别的抽象来表达某些内容)。在这里,您需要表达一些与普通 F# 代码非常接近的东西,我相信,最好用普通 F# 代码来表达。

关于f# - 无点函数中的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13895574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com