F# 返回结果类型为的异常

F# 返回结果类型为的异常,f#,F#,我尝试使用F#默认的错误:异常 我希望使用结果类型来处理错误,但是如果我尝试将异常的专门化(如ArgumentException)返回为错误,Visual Studio会说“此函数需要太多参数,或者在不需要函数的上下文中使用” 我的消息来源: let division (x: float) (y: float): Result<float, Exception> = if x = 0.0 then Error (ArgumentException ())

我尝试使用F#默认的错误:异常

我希望使用结果类型来处理错误,但是如果我尝试将异常的专门化(如ArgumentException)返回为错误,Visual Studio会说“此函数需要太多参数,或者在不需要函数的上下文中使用”

我的消息来源:

let division (x: float) (y: float): Result<float, Exception> =
    if x = 0.0 then
        Error (ArgumentException ())
    else
        Ok (x / y)
let除法(x:float)(y:float):结果=
如果x=0.0,则
错误(ArgumentException())
其他的
正常(x/y)

你混淆了类型和值(更新:这个答案主要是指你文章的第一个版本,TomasP的答案更适合更新代码)

  • 在方法签名中,
    Exception
    是泛型
    结果
    类型的类型参数
  • 在方法体中,当构造返回值时,需要使用
    异常
    类型的实例调用
    错误
您需要实际调用可能抛出的操作(
x/y
通常不会,如注释中所指出的),捕获异常,然后返回:

let division (x: float) (y: float): Result<float, Exception> =
    try
        let result = SomethingThatCouldThrow x y
        Ok result
    with 
    | e -> Error e
let除法(x:float)(y:float):结果=
尝试
让result=somethingthatldownthrow x y
Ok结果
具有
|e->错误e

顺便说一句,我不理解你“使用F#默认拥有的错误:异常”的目标。对错误条件的.Net默认处理是异常,是的。但是您在这里返回的是一个封装异常的类(在错误情况下)。

您混淆了类型和值(更新:这个答案主要是指您文章的第一个版本,Tomap的答案更适合更新的代码)

  • 在方法签名中,
    Exception
    是泛型
    结果
    类型的类型参数
  • 在方法体中,当构造返回值时,需要使用
    异常
    类型的实例调用
    错误
您需要实际调用可能抛出的操作(
x/y
通常不会,如注释中所指出的),捕获异常,然后返回:

let division (x: float) (y: float): Result<float, Exception> =
    try
        let result = SomethingThatCouldThrow x y
        Ok result
    with 
    | e -> Error e
let除法(x:float)(y:float):结果=
尝试
让result=somethingthatldownthrow x y
Ok结果
具有
|e->错误e

顺便说一句,我不理解你“使用F#默认拥有的错误:异常”的目标。对错误条件的.Net默认处理是异常,是的。但是您在这里返回的是一个封装异常的类(在错误情况下)。

代码的问题是,新创建的
ArgumentException
的类型与您在类型签名中指定的
异常
类型不同

您可以使用
:>
运算符安全地将
ArgumentException
强制转换为
Exception
,但F#不会自动插入强制转换,因此您必须自己编写:

let division (x: float) (y: float): Result<float, Exception> =
    if x = 0.0 then
        Error (ArgumentException () :> Exception)
    else
        Ok (x / y)

PS:我看到你说你得到了“函数需要太多参数”的错误。这很奇怪,也许在你的情况下还有更多的事情发生。当我尝试你的代码时,我得到的错误是“这个表达式应该有类型
异常
,但它是
参数异常
”,所以也许你也在重新定义一些标准类型

代码的问题在于,新创建的
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)

PS:我看到你说你得到了“函数需要太多参数”的错误。这很奇怪,也许在你的情况下还有更多的事情发生。当我尝试你的代码时,我得到的错误是“这个表达式应该有类型
异常
,但它是
参数异常
”,所以也许你也在重新定义一些标准类型

您的代码不一致。参数是
x
y
,但是可以将
a
b
分开。您正在检查
x
上的零,这是分母吗?您的代码不一致。参数是
x
y
,但是可以将
a
b
分开。您正在检查
x
上的零,这是分母吗?我知道您想说,但我不想抛出或检查异常,我只想在结果类型中包装一个异常(而不是使用“枚举”)。F#没有“new”关键字,所以我应该使用parentehsis来创建对象(我已经编辑了我的文章)。问题是我不能返回异常的专门化,例如ArgumentException。F#确实允许您使用
new
关键字创建对象的新实例。我能够使用
let e=new System.ArgumentException(“y”)
创建一个实例(假设您想先发制人地检查除法是否为零)。@Eric如果我尝试返回“Error e”,问题是相同的:“此表达式的类型应为'Exception',但此处的类型为'ArgumentException'”。您必须使用
:>
强制转换运算符将
参数异常
强制转换为
异常
。我只是在F#Interactive中做了这样的事情:
let(e2:Result)=Error(System.ArgumentException(“y”):>System.Exception)带有正常标志的FYI
1.0/0.0
不会抛出,而是返回:
inf
。即使是
0.0/0.0
也不会抛出异常,它会变成
nan
。我知道你想说,但我不想抛出或检查异常,我只想在结果类型中包装一个异常(而不是使用“枚举”)。F#没有“new”关键字,所以我应该使用