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"