我正在尝试使用F#默认的错误:例外。
我想用Result类型处理错误,但是如果我尝试返回Exception的特化,比如ArgumentException,就像错误一样,Visual Studio说“这个函数需要太多的参数,或者在一个函数的上下文中使用不期望“。
我的来源:
let division (x: float) (y: float): Result<float, Exception> =
if x = 0.0 then
Error (ArgumentException ())
else
Ok (x / y)
答案 0 :(得分:4)
您的代码存在的问题是新创建的ArgumentException
的类型与您在类型签名中指定的Exception
类型不同。
您可以使用ArgumentException
运算符安全地Exception
:>
,但F#不会自动插入强制转换,因此您必须自己编写:
let division (x: float) (y: float): Result<float, Exception> =
if x = 0.0 then
Error (ArgumentException () :> Exception)
else
Ok (x / y)
实际上,F#甚至可以从类型注释中推断出目标类型,所以你可以只写:
Error (ArgumentException () :> _)
PS:我看到你说你得到的“这个函数需要太多的参数”错误。这很奇怪,也许你的情况会有更多的事情发生。我在尝试您的代码时遇到的错误是“此表达式应该具有Exception
类型,但是ArgumentException
”所以也许您也在重新定义一些标准类型...
答案 1 :(得分:3)
你混淆了类型和值(更新:这个答案主要是指你帖子的第一个版本,TomasP的答案更适合更新的代码)
Exception
是通用Result
类型的类型参数。Error
类型的实例调用Exception
。你需要实际调用可能抛出的操作(x/y
通常不会,如评论中所指出的),捕获异常,然后返回:
let division (x: float) (y: float): Result<float, Exception> =
try
let result = SomethingThatCouldThrow x y
Ok result
with
| e -> Error e
顺便说一句,我不明白你的目标是“使用F#默认的错误:异常。” .Net默认处理错误条件是例外,是的。但是你在这里返回的是一个包装异常的类(在错误的情况下)。