如何扩展'T?

时间:2018-07-31 18:31:14

标签: generics f#

我正在尝试为'T编写扩展名,基本上是C#中的以下内容:

public static T With<T>(this T pObject, Action<T> pAction)
{
    pAction(pObject);
    return pObject;
}

我试图将其翻译为F#:

[<Extension>]
type Ext =
    [<Extension>]
    static member With<'T>(pObject: 'T, pAction: Action<'T>): 'T =
        pAction.Invoke(pObject);
        pObject;

module Extensions =
    type 'T with
        member this.With(pAction: Action<'T>): 'T = Ext.With(this, pAction);

但是这会产生错误“类型名称中的意外关键字'with'。”在最后一个片段中。

搜索返回了此结果,但显然仅适用于数组类型:How to define a type extension for T[] in F#?

如何扩展通用类型'T,或者有任何解决方法?

1 个答案:

答案 0 :(得分:5)

看来您可以按以下步骤完成此操作:

open System.Runtime.CompilerServices

[<Extension>]
type Ext =
    [<Extension>]
    static member With(obj, act) =
        act(obj)
        obj

// example of usage
"a".With(fun s -> printfn "%s" s).With(fun s-> printfn "%s" (s + "2"))

您实际上根本不需要显式类型(泛型或其他)。 F#将根据方法的主体推断出必要的类型。

当然,您可以以更F#的方式完成此操作,而无需使用任何扩展程序:

let withval = 
    fun act value ->
       act(value)
       value

// example of usage
"a"
   |> withval (fun s -> printfn "%s" s)
   |> withval (fun s-> printfn "%s" (s + "2"))