【发布时间】:2016-10-07 07:22:06
【问题描述】:
我在我的 F# 应用程序中使用 log4net,并希望通过创建一些函数来使日志记录更符合 F# 的习惯。
对于警告,我创建了以下函数:
let log = log4net.LogManager.GetLogger("foo")
let warn format = Printf.ksprintf log.Warn format
这很好用,我可以做到:
warn "This is a warning"
// and
warn "The value of my string is %s" someString
但是我想让它更通用,并且可以传入我想要的记录器。因此,我将该函数包装在另一个可以将 ILog 作为参数的函数中:
let getWarn (logger: log4net.ILog) =
fun format -> Printf.ksprintf logger.Warn format
我也试过了:
let getWarn (logger: log4net.ILog) format =
Printf.ksprintf logger.Warn format
当我现在这样使用它时:
let warn = getWarn log4net.LogManager.GetLogger("bar")
warn "This is a warning"
这可行,但是当我这样做时:
warn "The value of my string is %s" someString
我收到一个编译器错误提示 "The value is not a function and cannot be applied"
如果我删除第一个警告语句,它会起作用。
所以我猜编译器会根据我使用warn 的第一条语句推断类型,因此我需要始终以相同的方式使用它。
但为什么在我的第一个示例中不是这种情况,我直接使用warn 函数而不是通过getWarn?
【问题讨论】:
-
尝试像这样重写
getWarn函数:let getWarn (logger: log4net.ILog) format = Printf.ksprintf logger.Warn format。这会让编译器的类型推断找出你想要的吗?如果是这样,那么您遇到了某种问题,即它可以在经典函数声明中找出参数的类型,但当相同的参数在 lambda 表达式中时却不行。 -
不,我害怕同样的结果
-
尝试将管道转发到警告。
-
当您将鼠标悬停在
getWarn函数的format参数上时,您的IDE 会显示什么类型?是StringFormat<'T,'Result>吗?您看到的函数的warn和getWarn版本有哪些类型? -
@munn
warn: StringFormat<'a,unit> -> 'a,getWarn: ILog -> StringFormat<'a,unit> -> 'a如果我将format提供给 getWarn 函数,它会得到'a的类型
标签: f#