简体   繁体   中英

Injecting a function into a computation expression

The following code sample is from Scott Wlaschin's site F# for fun and profit .

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
        }

Is there a way to inject a function instead of printfn into the LoggingBuilder() ?

You can just add a parameter to the builder type:

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")

You could make the builder generic if you want to make the input type more specific than obj eg

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

let logger = new LoggingBuilder<int>(printfn "Got %i")

If your intention is to replace printfn with a logger such as NLog , you can use Printf.ksprintf .

open NLog
open NLog.Config
open NLog.Targets

let private logger =
    let config = new LoggingConfiguration()
    let consoleTarget = new ColoredConsoleTarget()
    config.AddTarget("console", consoleTarget)
    consoleTarget.Layout <- Layouts.SimpleLayout.FromString
        @"${longdate}|${level:uppercase=true}|${logger}|${message}"

    let rule = new LoggingRule("*", LogLevel.Debug, consoleTarget)
    config.LoggingRules.Add rule

    LogManager.Configuration <- config
    LogManager.GetLogger "MyLogger"

type LoggingBuilder(lf: string -> unit) =
    let log format =
        let doAfter (s: string) = lf s
        Printf.ksprintf doAfter format

    member this.Bind(x, f) = 
        log "%A" x
        f x

    member this.Return(x) = 
        x

let logger = new LoggingBuilder(logger.Info)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM