以下代码示例来自Scott Wlaschin的网站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
}
有没有办法将函数而不是printfn
注入LoggingBuilder()
?
答案 0 :(得分: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")
如果要使输入类型比obj
更具体,可以使构建器通用。例如
type LoggingBuilder<'a>(lf: 'a -> unit) =
...
let logger = new LoggingBuilder<int>(printfn "Got %i")
答案 1 :(得分:0)
如果您打算将printfn
替换为NLog等记录器,则可以使用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)