将函数注入计算表达式

kas*_*rhj 3 f# functional-programming dependency-injection

以下代码示例来自Scott Wlaschin的网站F#,以获得乐趣和利润.

type LoggingBuilder() =
    let log p = printfn "expression is %A" p

    member this.Bind(x, f) = 
        log x
        f x

    member this.Return(x) = 
        x

let logger = new LoggingBuilder()

let loggedWorkflow = 
    logger
        {
        let! x = 42
        let! y = 43
        let! z = x + y
        return z
        }
Run Code Online (Sandbox Code Playgroud)

是否有办法注入一个函数,而不是printfn进入LoggingBuilder()

Lee*_*Lee 6

您只需将参数添加到构建器类型:

type LoggingBuilder(lf: obj -> unit) =
    let log p = lf p

    member this.Bind(x, f) = 
        log x
        f x

    member this.Return(x) = 
        x

let logger = new LoggingBuilder(printfn "expression is %A")
Run Code Online (Sandbox Code Playgroud)

如果要使输入类型比例obj如更具体,则可以使构建器成为通用的

type LoggingBuilder<'a>(lf: 'a -> unit) =
    ...

let logger = new LoggingBuilder<int>(printfn "Got %i")
Run Code Online (Sandbox Code Playgroud)