F# 是否可以创建一个记录类型,其字段是一个接受泛型参数的函数,而不在创建记录时指定类型?

F# 是否可以创建一个记录类型,其字段是一个接受泛型参数的函数,而不在创建记录时指定类型?,f#,F#,我想定义以下记录类型: type LogFuncs = { LogWithLabel : string -> 'a -> unit LogWithLabelAndReturn : string -> 'a -> 'a } 其目的是我可以定义一个string->unit函数,然后使用它派生几个方便的函数,如下所示: let makeLogFuncs outputFunc = let logWithLabelFunc label value = sp

我想定义以下记录类型:

type LogFuncs = {
    LogWithLabel : string -> 'a -> unit
    LogWithLabelAndReturn : string -> 'a -> 'a }
其目的是我可以定义一个
string->unit
函数,然后使用它派生几个方便的函数,如下所示:

let makeLogFuncs outputFunc =
    let logWithLabelFunc label value = sprintf "%s: %A" label value |> outputFunc
    let logWithLabelAndReturnFunc label value = logWithLabelFunc label value; value
    {   LogWithLabel = logWithLabelFunc
        LogWithLabelAndReturn = logWithLabelAndReturnFunc  }

但是,编译器不允许我在不指定
的情况下执行此操作。我认为不可能对记录类型执行此操作。但是我可以定义一个类,它提供了我想要的机制:

type Logger (outputFunc: string->unit) =
    member __.LogWithLabel label value = sprintf "%s: %A" label value |> outputFunc
    member x.LogWithLabelAndReturn label value = x.LogWithLabel label value; value
然后我可以做:

let log = new Loggery (printfn "%s")

let ``result should equal 5`` = 5 |> log.LogWithLabelAndReturn "Beans"

…并正确打印
“Beans:5”
并返回
5

您可以使记录本身具有通用性:

type LogFuncs<'a> = {
    LogWithLabel : string -> 'a -> unit
    LogWithLabelAndReturn : string -> 'a -> 'a }

正如Overlord Zurg提供的答案所暗示的那样,OP方法是非常面向对象的,因此如果您希望以这种方式设计系统,请使用对象。

您将把关于什么是
'a
的信息存储在哪里,以及如何以类型安全的方式使用它。如果您不关心类型安全,只需使用objectI在记录时不一定关心'a'的类型,但是当我记录并返回它时,我希望返回类型与输入类型完全相同,而不是obj.IMO接口(您可以这样做)和对象表达式(创建这样的接口)是一个可行的替代记录在这里-一些时间前关于一些非常相似的-也许你觉得它有趣
(makeLogFuncs (printfn "%s")).LogWithLabel "Number" 42
(makeLogFuncs (printfn "%s")).LogWithLabelAndReturn "Number" 42
(makeLogFuncs (printfn "%s")).LogWithLabel "Text" "Foo"
(makeLogFuncs (printfn "%s")).LogWithLabelAndReturn "Text" "Foo"