Asynchronous 异步不可知高阶函数

Asynchronous 异步不可知高阶函数,asynchronous,f#,higher-order-functions,Asynchronous,F#,Higher Order Functions,假设我们有一个提供高阶函数的库applyTest 这是否可以与异步函数asyncFunction一起使用,同时保留异步代码的优点 该库是否可以设计为更好地支持异步应用程序,而无需专门提供异步版本 let applyTest f = f 2 > 0 let syncFunction x = x - 1 let asyncFunction x = x - 2 |> async.Return async { let a = applyTest sync

假设我们有一个提供高阶函数的库
applyTest

这是否可以与异步函数
asyncFunction
一起使用,同时保留异步代码的优点

该库是否可以设计为更好地支持异步应用程序,而无需专门提供异步版本

let applyTest f =
    f 2 > 0

let syncFunction x =
    x - 1

let asyncFunction x =
    x - 2 |> async.Return

async {
    let a = applyTest syncFunction
    let b = applyTest (asyncFunction >> Async.RunSynchronously)
    printfn "a = %b, b = %b" a b
}
|> Async.RunSynchronously

如果您不想丢失强类型检查,或者不想像示例中那样同步运行异步计算,那么需要提供一个单独的异步版本。这两件事都应该尽量避免

如果要避免重复实际测试部分(
f2>0
),可以将其拆分为一个函数,将参数
2
传递给函数,并检查值是否大于零:

// LIBRARY CODE

let checkValue x = x > 0

// This function is generic so it can return a value or an async value
// (int -> 'a) -> 'a
let runTestFunction f = f 2

// (int -> int) -> bool
let applyTest f = f |> runTestFunction |> checkValue

// (int -> Async<int>) -> Async<bool>
let applyTestAsync f = async {
    let! value = runTestFunction f // use let! to await the value
    return checkValue value }

// USAGE

let syncFunction x = x - 1
let asyncFunction x = x - 2 |> async.Return

async {
    let a = applyTest syncFunction
    let! b = applyTestAsync asyncFunction // use let! to await the test result
    printfn "a = %b, b = %b" a b
}

谢谢,我将为我的架构尝试一种不同的方法。我发现了许多有趣的博客,探讨了这一领域,从一个类似的问题开始。尽管一些业务逻辑溢出到了外层,但它实际上可能会简化我的总体设计。
type Test =
    static member Apply f = applyTest f
    static member Apply f = applyTestAsync f

// USAGE

async {
    let a = Test.Apply syncFunction
    let! b = Test.Apply asyncFunction // We still need to consume this differently with a let!
    printfn "a = %b, b = %b" a b
}