10

The question is simple and. although it is obvious the answer, I had to face a strange situation where the fsharp told me something a bit strange. Here's the story:

The question is: Does F# automatically make every type inherit the Object class? I suppose YES and I am certain of this because there would be so many complications if that were not the case.

But here's a fact. I was writing this piece of code:

type MyType =
   val myval: int
   override self.ToString = "Hello MyType"

Well, fsharp compiler told me it is not correct using overrid because he does not find any method called ToString to override. I so compiled this code:

type MyType =
   val myval: int
   member self.ToString = "Hello MyType"

And everything worked fine. mmmmmm What's happening??? Isn't FSharp supposed to inherit every object from Object?

Andry
  • 16,172
  • 27
  • 138
  • 246

3 Answers3

14

You forgot parens:

type MyType =
   val myval: int
   override self.ToString() = "Hello MyType"

In your original code with parens omitted you were trying to override property ToString.

Anton Tykhyy
  • 19,370
  • 5
  • 54
  • 56
desco
  • 16,642
  • 1
  • 45
  • 56
  • 4
    +1 but I'm staring myself blind simply looking for the 'Yes' in your answer. – Grant Thomas Feb 14 '11 at 14:20
  • your answer fixes the OP's initial code but doesn't answer the question of why the second version works. – Chris Haas Feb 14 '11 at 14:44
  • 1
    The second version works because nothing prevents one from creating a new `ToString` property. – Anton Tykhyy Feb 14 '11 at 14:59
  • Yes correct, thank you desco... it interpreted it not as a function ut as a value :) – Andry Feb 14 '11 at 15:00
  • OKOK quite the second works because it is recognized not as a function member but a a value member... that's why it does not tell me to put override, because it does not hide anything :) – Andry Feb 14 '11 at 15:01
5

Desco already explained the probelm with your snippet.

F# behaves just like C#, which means that all types inherit from Object, although with a slightly subtle behavior of value types. When you have a variable of a value type, it cannot be directly treated as Object and need to be boxed (to a .NET reference type that inherits from Object).

This can cause some confusing errors with type inference:

let foo x = 
  match x with 
  | :? System.Random as rnd -> rnd.Next()
  | _ -> 0

When you write this, you get an error message:

error FS0008: This runtime coercion or type test from type 'a to Random involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed.

If everything inherited from Object in the strict sense, then F# compiler should be able to convert any type parameter to Object, but that's not allowed. The problem is that value types need boxing, so you need to write match box x with ....

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
1

No. There are types that do not derive from object. Interfaces, for example, are types that do not derive from object. See http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx for more detail.

phoog
  • 42,068
  • 6
  • 79
  • 117