gpt4 book ai didi

F#:有些、无或异常(exception)?

转载 作者:行者123 更新时间:2023-12-03 23:34:01 27 4
gpt4 key购买 nike

我最近一直在自学 F#,我来自命令式 (C++/C#) 背景。作为练习,我一直在研究可以处理矩阵的函数,例如加法、乘法、求行列式等。在这方面一切都进展顺利,但我发现当涉及到处理时,我可能没有做出最好的决定无效输入,例如:

// I want to multiply two matrices
let mult m1 m2 =
let sizeOK = validateDims m1 m2

// Here is where I am running to conceptual trouble:
// In a C# world, I would throw an exception.
if !sizeOK then
raise (InvalidOperationException("bad dimensions!")
else
doWork m1 m2

因此,虽然这在技术上可行,但这是否适用于函数式语言?是否符合函数式编程的精神?或者将其重写为更有意义:
let mult m1 m2 =
let sizeOK = validateDims m1 m2

if !sizeOK then
None
else
Some doWork m1 m2

在这种情况下,我返回了一个选项,它在矩阵周围添加了一个额外的层,但我也可以使用函数的结果,即使在程序稍后的某个时间点使用模式匹配等失败情况(无)。那么对于这些​​类型的场景有最佳实践吗?函数式程序员会做什么?

最佳答案

由于以下原因,我倾向于避免异常:

  • .NET exceptions are slow
  • 异常以一种意想不到的方式改变程序的控制流,这使得推理
  • 变得更加困难。
  • 在紧急情况下经常会出现异常,而您可以通过使用选项进行故障安全。

  • 在您的情况下,我将遵循 F# 核心库约定(例如 List.tryFindList.find 等)并创建两个版本:
    let tryMult m1 m2 =
    let sizeOK = validateDims m1 m2

    if not sizeOK then
    None
    else
    Some <| doWork m1 m2

    let mult m1 m2 =
    let sizeOK = validateDims m1 m2

    if not sizeOK then
    raise <| InvalidOperationException("bad dimensions!")
    else
    doWork m1 m2

    这个例子不足以使用异常。 mult包含 C# 兼容性的函数。在 C# 中使用您的库的人没有模式匹配来轻松分解选项。

    选项的一个缺点是它们没有给出函数不产生值的原因。这里太过分了;一般 Choice (或 Haskell 术语中的任一个 monad)更适合 error handling :
    let tryMult m1 m2 =
    // Assume that you need to validate input
    if not (validateInput m1) || not (validateInput m2) then
    Choice2Of2 <| ArgumentException("bad argument!")
    elif not <| validateDims m1 m2 then
    Choice2Of2 <| InvalidOperationException("bad dimensions!")
    else
    Choice1Of2 <| doWork m1 m2

    遗憾的是,F# Core 缺少操作 Choice 的高阶函数。您可以在 FSharpX 中找到这些功能或 ExtCore图书馆。

    关于F#:有些、无或异常(exception)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18469815/

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