Exception F#异常处理构造

Exception F#异常处理构造,exception,exception-handling,f#,Exception,Exception Handling,F#,为什么F#自然不支持try/with/finally块 尝试一些东西,处理它引发的任何异常,至少记录异常,然后确保在所有这些之后执行一些代码,这难道没有意义吗 当然可以 try try ... with ex -> ... finally ... 但这似乎太做作了,它清楚地表明“F#反对try/with/finally”。为什么呢 但这似乎太做作了,它清楚地表明“F#反对try/with/finally”。为什么呢 我想F#可能根本不支持异常处理。

为什么F#自然不支持try/with/finally块

尝试一些东西,处理它引发的任何异常,至少记录异常,然后确保在所有这些之后执行一些代码,这难道没有意义吗

当然可以

try
    try
        ...
    with ex -> ...
finally
    ...
但这似乎太做作了,它清楚地表明“F#反对try/with/finally”。为什么呢

但这似乎太做作了,它清楚地表明“F#反对try/with/finally”。为什么呢

我想F#可能根本不支持异常处理。为了实现.NET互操作性,它必须支持它们,但基本上,在函数式编程中没有异常处理*

抛出/捕获异常意味着执行类型系统甚至没有注意到的“无处跳转”,这从根本上违背了功能哲学

您可以使用纯函数(一元)代码包装异常。根据基础类型系统,所有错误都通过值进行处理,并且没有跳转/副作用

而不是编写函数

let readNumber() : int = ...
这可能会抛出任意异常,您只需声明

let readNumber() : int option = ...
这使得这一点通过其类型签名自动清除


*这并不意味着我们不处理异常情况,这只是关于.NET/C++中的异常处理。

我将在回答中澄清我的评论

  • 我坚持认为,没有理由假定您希望捕获异常并在同一级别完成某些资源。也许你已经习惯了用一种同时处理这两种语言的方式,但这只是巧合。当您不捕获内部块中的所有异常时,终结非常方便
    try…with
    用于捕获异常,以便正常继续计算。这两者之间根本没有关系(如果有什么关系的话,它们的方向是相反的:你是抓住了异常,还是让它通过了?)

  • 为什么您必须完成任何事情?GC不应该为您管理未引用的资源吗?啊。。。但是,该语言试图让您能够访问具有副作用的系统原语,包括显式分配和取消分配。您必须取消分配您已分配的(在所有情况下)。。。难道你不应该责怪系统提供的糟糕界面而不是F#,在这种情况下F#只是信使吗


  • 正交性?您可以简单地将try嵌套在try finally中,如您所示。(我认为,无论如何,这就是IL水平的情况。)

    这样说,最后尝试是在将来的语言版本中可以考虑的事情。 就我个人而言,我只是偶尔想要它,但是当你确实需要它的时候,需要做额外的嵌套/缩进是有点麻烦的。一般来说,我发现我很少编写异常处理代码,通常只是其中之一(例如,最终恢复不变或其他事务语义,或在应用程序顶部附近的“捕获”记录异常或显示用户诊断)


    但是我认为这里没有太多关于语言设计的“阅读”内容。

    正如有人已经提到的,您通常会使用
    try with finally
    来确保在出现异常时正确释放所有资源。我认为在大多数情况下,使用
    use
    关键字可以更轻松地做到这一点:

    let input = 
      try
        use stream = new FileStream("C:\temp\test.txt");
        use rdr = new StreamReader(stream);
        Some(rdr.ReadToEnd())
      with :? IOException as e -> 
        logError(e)
        None
    

    我认为这就是为什么您不需要像在其他语言中那样频繁地尝试finally。但当然,在某些情况下,您可能需要它(但您当然可以通过使用对象表达式创建
    IDisposable
    的实例来避免这种情况(这在语法上非常容易).但我认为这是如此罕见,以至于F#团队真的不需要担心这一点。

    没有详细说明,因为详细说明都在后面

    谢尔盖·利丁

    参见:第14章,托管异常处理

    "finallyfault处理程序不能与其他处理程序和平共存,因此,如果受保护的块具有finallyfault处理程序,则它不能具有任何其他处理程序。要将finallyfault处理程序与其他处理程序组合,需要嵌套该保护块ed和处理程序在其他防护块内阻塞,…,因此每个最终故障处理程序都有自己的个人防护块。”

    第300页

    try/catch使用错误处理程序,try/finally使用最终处理程序

    见:

    如果在异常块中发出错误处理程序,该异常块也包含 catch处理程序或最终处理程序,生成的代码是 无法验证


    <> P.>所有的.NET语言都可以被认为是使用语法激增,因为F是如此新奇,他们还没有实现它。没有伤害没有ford.< /P>是人工的吗?我只看到一个冗余的三个字母关键字。C++不被指责为“反对变量”,因为你必须写一个冗余的int。"还有,我不知道你是如何使用异常的,但是当我编程时,异常不是用来记录的。如果你有一个值可以在异常发生时提供给你,请返回该值,否则,让异常进一步膨胀,但我不明白记录与它有什么关系…@Pascal Cuoq:请不要对h进行假设我如何使用异常。如果我出于任何原因想要记录异常,它不会自动暗示我使用异常进行记录,正如您的评论暗示的那样。此外,这不是一个关于如何处理异常以及如何处理异常的问题,但这是一个非常重要的问题