Reputation:
How do I override tostring function on a built in collection such as map or sequence such that printfn will use this new custom tostring function?
I would guess it should be something like
type seq<'T> with
override xs.Tostring() =
"blabla"
however this just gives the error "type abbreviations cannot have augmentations".
I then looked at msdn and found following about type extension http://msdn.microsoft.com/en-us/library/dd233211.aspx
it states that I should be able to extend for example int32 and sequence like following
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 }
First example works fine however for the second one I just get an error saying "type abbreviations cannot have members".
I am currently using .Net 4.5.1 and F# 3.1
Upvotes: 2
Views: 1204
Reputation: 16792
Type extensions can be thought of more or less like extensions members. You are not creating a new type, you are just declaring methods, properties, etc which the language allows you to consume with a syntax that looks like they were part of an existing type.
A true override can only be done when you have created a new class inheriting from the guy whose members you wish to override.
Unfortunately, the F# collection types are either sealed or nonpublic (or both), so you can't do this. It would probably not work out well, anyway, since these types are hardwired all over the compiler/runtime.
type myList<'t>() =
inherit list<'t>() // error FS0945: Cannot inherit a sealed type
override this.ToString() = "woooo"
You can work around in various ways, but it's not quite seamless. Here's a basic approach that works pretty well
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]
Upvotes: 6