1

例如,我可以这样做:

let mutable divide = fun (a,b) -> a / b
let checkZero (a,b) = if b = 0 then failwith "wrong" else (a,b)
divide <- checkZero >> divide

divide (5,3)

但是如果我想形成一个柯里化函数怎么办:

let mutable divide = fun a b -> a / b
let checkZero a b = if b = 0 then failwith "wrong" else ... // How return
                                                     // the two argument
divide <- checkZero >> divide

divide 5 3

我可以这样做吗?

4

3 回答 3

2

的类型>>是:

> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@3-1>

所以checkZeroanddivide应该遵守 type: 'a -> 'b

于 2013-07-19T14:48:24.197 回答
2

不是直接,而是做这样的事情:

let curry f a b = f (a,b)
let uncurry f (a,b) = f a b

let mutable divide = fun a b -> a / b
let checkZero a b = if b = 0 then failwith "wrong" else (a,b)

divide <- let f = (uncurry checkZero) >> (uncurry divide) in curry f
于 2013-07-19T16:00:06.137 回答
1

因此,您有两个谓词checkZeroand divide,并且您想将相同的参数(元组)应用于这两个谓词。

就像在这个问题中一样:包装checkZero成一个组合器,它将忽略返回值并返回一个原始参数。请注意,将在需要时抛出异常。这样的组合器在 WebSharper 中定义:

let ( |>! ) x f = f x; x
// Usage:
let checkZero a b = if b = 0 then failwith "wrong" else ()
let ret = (5,3) |>! checkZero |> divide

这只有在checkZero返回时才有效unit。如果它应该返回其他东西(并且返回值应该被强制忽略),那么这个定义就可以了:

let ( |>!! ) x f = ignore(f x); x
// Usage:
let checkZero a b = if b = 0 then failwith "wrong" else "42"
let ret = (5,3) |>!! checkZero |> divide

上面的解决方案似乎是最干净的,因为它不需要修改您的谓词。组合器将可在整个项目中重复使用。

于 2013-07-19T17:43:42.723 回答