1

我遇到以下问题:

let safeDiv x y = 
  match (x,y) with
  | (_, Some 0) -> None
  | (Some xx, Some yy) -> Some (xx/yy)
  | _ -> None

当我像这样在 Visual Studio 的交互式窗口中运行这个简单的函数时:

safeDiv 4 2

我收到以下错误...

此表达式应具有 int 类型选项,但此处具有 int 类型。

难道是我打算使用safeDiv Some(4) Some(2)?这也行不通...

4

4 回答 4

4

好的,这有点矫枉过正,但我​​最近实际上做了类似的事情。

首先,我为选项类型定义了一个计算表达式构建器:

type OptionBuilder() =
    member this.Bind(x, f) = Option.bind f x
    member this.Return(x) = Some x
    member this.ReturnFrom(x) = x

let opt = new OptionBuilder()

然后我定义了一个 float -> float -> float 选项的函数 sub

let sub x y = if y = 0.0 then None else Some (x / y)

最后我使用 OptionBuilder 将 saveDiv 定义为浮动选项 -> 浮动选项 -> 浮动选项

let safeDiv x y = opt { let! a = x
                        let! b = y
                        return! sub a b }

您可以在 wikibooks 上阅读有关计算表达式的更多信息:http ://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions

如果你想深入了解这背后的理论,你可以阅读 Tomas Petricek 和 Don Syme 的这篇论文:http: //www.cl.cam.ac.uk/~tp322/drafts/notations.pdf

于 2013-10-08T10:52:48.657 回答
1

你的第二个版本很接近。

它应该是

safeDiv (Some(4)) (Some(2))

需要额外的括号以确保以正确的顺序应用函数。

于 2013-10-08T06:13:25.540 回答
1

您构造了一个具有签名的函数safeDiv : int option -> int option -> int option。您需要使用一个条目safeDiv (Some 4) (Some 2)来按原样使用您的功能。

于 2013-10-08T06:15:12.123 回答
0

问题在于 int*int 类型的 (4, 2) 与表达式 (_, Some 0) 和 (Some xx, Some yy) 的匹配。整个函数可以简化:

let safeDiv x y = 
    match (x,y) with
    | (_, 0) -> None
    | (_, _) -> Some (x/y)

使以下调用有效

safeDiv 4 2
于 2016-04-18T11:28:28.317 回答