我使用第三方库(Sauve.IO)来定义标准绑定运算符>> =:
val inline (>>=) : first:('T -> Async<'U option>) -> second:('U -> Async<'V option>) -> input:'T -> Async<'V option>
我还有一个内部库,它也希望通过类型签名
定义运算符Async<Response<'a>> -> ('a -> Async<Response<'b>>) -> Async<Response<'b>>
在不影响重载内联函数的限制的情况下,在同一命名空间/模块中使用这两个函数的最简洁方法是什么?
答案 0 :(得分:3)
答案 1 :(得分:2)
您可以利用F#的静态解析ad-hoc多态性:将合格的运算符调用隐藏在单独的重载运算符后面;然后定义另一个内联运算符以供实际使用。
type Foo = Foo with
static member ($) (_ : Foo, first : _ -> Async<_ option>) =
fun second value -> Module1.(>>=) first second value
static member ($) (_ : Foo, arg1 : Async<Response<_>>) =
Module2.(>>=) arg1
let inline (>>=) arg1 arg2 = (Foo $ arg1) arg2
答案 2 :(得分:0)
两个运营商是否都具有相同的名称(>>=)
?
如果是这样,我认为Suave的运营商带有它自己的模块或命名空间?
在这种情况下,您可以限定其运算符附加其模块/命名空间名称,如Suave.(>>=)
,但在这种情况下,您必须将其称为通常的函数。这是一个简化的例子:
module Suave =
let inline (>>=) a b = a + 2 * b
module Mine =
open Suave
let (>>=) a b = a - 3 * b
let r1 = Suave.(>>=) 1 3
let r2 = 1 >>= 3
结果:
val r1 : int = 7
val r2 : int = -8