例如,我可以这样做:
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)
但如果我想形成一个currying函数怎么办:
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
我能这样做吗?
答案 0 :(得分:2)
>>
的类型是:
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@3-1>
因此checkZero
和divide
应遵守类型:'a -> 'b
。
答案 1 :(得分: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
答案 2 :(得分:1)
所以你有两个谓词,checkZero
和divide
,并且你想对这两个谓词应用相同的参数(一个元组)。
就像在this question中一样:将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
上面的解决方案似乎是最干净的,因为它不需要修改谓词。组合器可以在整个项目中重复使用。