F# 中 kprintf 的语法问题
syntax issue around kprintf in F#
我有一个使用 NLog 的项目,记录器周围有一个包装器,以便在某些区域关闭注销:
member this.SetQuiet q = quiet <- q
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) format
member this.Debug format = Printf.kprintf (fun s -> if not quiet then logger.Debug(s)) format
member this.Info format = Printf.kprintf (fun s -> if not quiet then logger.Info(s)) format
member this.Warn format = Printf.kprintf (fun s -> if not quiet then logger.Warn(s)) format
member this.Error format = Printf.kprintf (fun s -> if not quiet then logger.Error(s)) format
member this.Fatal format = Printf.kprintf (fun s -> if not quiet then logger.Fatal(s)) format
效果很好,但我有一个问题:
logger.Info "hello"
logger.Info <| "hello"
将正常工作,而:
"hello" |> logger.Info
将不会编译并出现此错误:
typecheck error The type 'string' is not compatible with the type 'Printf.StringFormat<'a,string>'
有人能解释一下为什么会失败吗?这里仍然应该遵守 kprintf-continuation-format 的顺序,不是吗?
有解决办法吗?原因是我试图做一个 'tee' 以非冗长的方式记录消息(T 恤只是应用一个函数然后 returns 原始参数):
"my messsage"
|> tee logger.Info
|> Result.Ok
发生这种情况是因为 printf
和类似的方法使用格式。它允许以类型安全的方式使用这些方法。例如 printfn "%d"
强制整数作为参数
printfn "%d" 3
printfn "%d" 3.14 // error
printfn "%s %f"
强制执行字符串和浮点数。
printfn "%s %f" "Hello" 3.14
printfn "%s %f" '3' 14 // error
这意味着你应该这样改变方法(添加"%s"
)
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) "%s" format
我有一个使用 NLog 的项目,记录器周围有一个包装器,以便在某些区域关闭注销:
member this.SetQuiet q = quiet <- q
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) format
member this.Debug format = Printf.kprintf (fun s -> if not quiet then logger.Debug(s)) format
member this.Info format = Printf.kprintf (fun s -> if not quiet then logger.Info(s)) format
member this.Warn format = Printf.kprintf (fun s -> if not quiet then logger.Warn(s)) format
member this.Error format = Printf.kprintf (fun s -> if not quiet then logger.Error(s)) format
member this.Fatal format = Printf.kprintf (fun s -> if not quiet then logger.Fatal(s)) format
效果很好,但我有一个问题:
logger.Info "hello"
logger.Info <| "hello"
将正常工作,而:
"hello" |> logger.Info
将不会编译并出现此错误:
typecheck error The type 'string' is not compatible with the type 'Printf.StringFormat<'a,string>'
有人能解释一下为什么会失败吗?这里仍然应该遵守 kprintf-continuation-format 的顺序,不是吗?
有解决办法吗?原因是我试图做一个 'tee' 以非冗长的方式记录消息(T 恤只是应用一个函数然后 returns 原始参数):
"my messsage"
|> tee logger.Info
|> Result.Ok
发生这种情况是因为 printf
和类似的方法使用格式。它允许以类型安全的方式使用这些方法。例如 printfn "%d"
强制整数作为参数
printfn "%d" 3
printfn "%d" 3.14 // error
printfn "%s %f"
强制执行字符串和浮点数。
printfn "%s %f" "Hello" 3.14
printfn "%s %f" '3' 14 // error
这意味着你应该这样改变方法(添加"%s"
)
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) "%s" format