如何覆盖内置集合中的 tostring
how to override tostring on built in collection
如何覆盖内置集合(例如映射或序列)的 tostring 函数,以便 printfn 将使用这个新的自定义 tostring 函数?
我猜应该是这样的
type seq<'T> with
override xs.Tostring() =
"blabla"
然而这只会给出错误 "type abbreviations cannot have augmentations"。
然后我查看了 msdn,发现了以下关于类型扩展的内容 http://msdn.microsoft.com/en-us/library/dd233211.aspx
它指出我应该能够扩展例如 int32 和序列,如下所示
type System.Int32 with
member this.FromString( s : string ) =
System.Int32.Parse(s)
type seq<'T> with
/// Repeat each element of the sequence n times
member xs.RepeatElements(n: int) =
seq { for x in xs do for i in 1 .. n do yield x }
第一个示例工作正常但是对于第二个示例我只是收到一条错误消息 "type abbreviations cannot have members".
我目前正在使用 .Net 4.5.1 和 F# 3.1
类型扩展可以被认为或多或少像扩展成员。您不是在创建 new 类型,您只是在声明方法、属性等,语言允许您使用看起来像是 一部分的语法来使用这些方法、属性等现有 类型。
只有当您创建了一个新的 class 继承自您希望覆盖其成员的人时,才能完成真正的覆盖。
不幸的是,F# 集合类型是密封的或非公共的(或两者),因此您不能这样做。无论如何,它可能不会很好地工作,因为这些类型在整个 compiler/runtime.
中都是硬连接的
type myList<'t>() =
inherit list<'t>() // error FS0945: Cannot inherit a sealed type
override this.ToString() = "woooo"
您可以通过多种方式解决问题,但并不是天衣无缝。这是一个非常有效的基本方法
module CustomStr =
type ToStringWrapper(toString) =
override this.ToString() = toString ()
let list lst = ToStringWrapper(fun _ -> lst |> List.map (sprintf "[%O]") |> String.concat "")
let seq s = ToStringWrapper(fun _ -> s |> Seq.map (sprintf "{%O}") |> String.concat "")
{1..3} |> CustomStr.seq |> printfn "%A"
[1;2;3] |> CustomStr.list |> printfn "%A"
// {1}{2}{3}
// [1][2][3]
如何覆盖内置集合(例如映射或序列)的 tostring 函数,以便 printfn 将使用这个新的自定义 tostring 函数?
我猜应该是这样的
type seq<'T> with
override xs.Tostring() =
"blabla"
然而这只会给出错误 "type abbreviations cannot have augmentations"。
然后我查看了 msdn,发现了以下关于类型扩展的内容 http://msdn.microsoft.com/en-us/library/dd233211.aspx
它指出我应该能够扩展例如 int32 和序列,如下所示
type System.Int32 with
member this.FromString( s : string ) =
System.Int32.Parse(s)
type seq<'T> with
/// Repeat each element of the sequence n times
member xs.RepeatElements(n: int) =
seq { for x in xs do for i in 1 .. n do yield x }
第一个示例工作正常但是对于第二个示例我只是收到一条错误消息 "type abbreviations cannot have members".
我目前正在使用 .Net 4.5.1 和 F# 3.1
类型扩展可以被认为或多或少像扩展成员。您不是在创建 new 类型,您只是在声明方法、属性等,语言允许您使用看起来像是 一部分的语法来使用这些方法、属性等现有 类型。
只有当您创建了一个新的 class 继承自您希望覆盖其成员的人时,才能完成真正的覆盖。
不幸的是,F# 集合类型是密封的或非公共的(或两者),因此您不能这样做。无论如何,它可能不会很好地工作,因为这些类型在整个 compiler/runtime.
中都是硬连接的type myList<'t>() =
inherit list<'t>() // error FS0945: Cannot inherit a sealed type
override this.ToString() = "woooo"
您可以通过多种方式解决问题,但并不是天衣无缝。这是一个非常有效的基本方法
module CustomStr =
type ToStringWrapper(toString) =
override this.ToString() = toString ()
let list lst = ToStringWrapper(fun _ -> lst |> List.map (sprintf "[%O]") |> String.concat "")
let seq s = ToStringWrapper(fun _ -> s |> Seq.map (sprintf "{%O}") |> String.concat "")
{1..3} |> CustomStr.seq |> printfn "%A"
[1;2;3] |> CustomStr.list |> printfn "%A"
// {1}{2}{3}
// [1][2][3]