tags:

views:

204

answers:

4

I don't know if the title of the question is clear but I am wondering the actual types of custom F# types.

Like in C#, there are value types and reference types. For F#, is there a single type that governs the type system?

Are they all value types (since they are immutable by default)?

Or is/are there completely new types that's nothing like value/reference type(s)?

Any info would be helpful.

+2  A: 

Value and Reference types come from .NET, not C#. Not an expert on F#, but I have to believe that their types are the same, since it's a first-class .NET language and touts interoperability with C#.

Also, Reference types can be immutable (e.g. String), and value types can be mutable (as nearly all in .NET are) -- these have nothing to do with mutable/immutable choice.

Edit: corrected based on comment.

Lou Franco
An irrelevent nitpick: The majority of the framework's built-in public value types are immutable.
LukeH
I quickly looked up a few value types I use and they are immutable! -- I guess I never really try to change them, because I didn't inherently think of them as immutable. Thanks.
Lou Franco
+2  A: 
Henk Holterman
+1  A: 

You have interfaces, classes and structs in F# as well - these map as expected to other CLR languages like C#, so for interface purposes you should restrict yourself to these types.

As for discriminated unions and records the mapping is more complicated, not something you want to do if you don't absolutely have to.

BrokenGlass
+8  A: 

F# has various kinds of types. Standard .NET types (that also exist in C#) such as class, interfaces and delegates are mapped directly to the corresponding CLR representation.

You can also define value type using the Struct attribute (in which case, you get a type corresponding to C# struct) and an enumeration like this:

[<Struct>]
type ValueType(a:int) =
   member x.A = a

type Enumeration = 
  | First = 1
  | Second = 2

The remaining F# types are specific to F# and don't have any standard representation in CLR. F# compiler encodes them as a class (or several classes).

  • Record is simply a class with properties corresponding to the fields of the record.
  • Tuple is represented using a generic Tuple<...> class (which is new in .NET 4.0)

  • Function value is represented using a generic FSharpFunc<...> type. This allows F# to implement currying & partial function application, so it is a bit tricky. For example, int -> int -> int would be FSharpFunc<int, FSharpFunc<int, int>>. The type has a single Invoke method that you can use to call it with the first parameter. F# also generates a derived type that contains Invoke method taking all the parameters, which is more efficient and is used most of the time.

  • Discriminated union is represented as a class hierarchy with an abstract base class (with the same name as the union type) and a subclass for each of the cases. For example:

    type Shape = 
      | Rectangle of int * int * int * int
      | Circle of int * int * int 
    

    This would create an abstract base class Shape and two derived concrete classes Rectangle and Circle (actually, nested classes in the Shape class). These derived classes would contain the fields needed to store the properties of the case (e.g. location of a rectangle).

If you want to know more, you can take a look at the Adventures in F# series by Jomo Fisher.

Tomas Petricek
Nice answer! BTW, `FastFunc` have been renamed to `FSharpFunc` and other specific F# types are prefix with FSharp as well ( `FSharpOption`, `FSharpRef`, etc).
Stringer Bell
@Stringer: Thanks for the correction! I'm still not sure if I included all types - there is a quite a few of them!
Tomas Petricek
@Thomas: Thanks, so the ValueType is not really a struct unless you say you? If so, then how does it behave? Like a different type than class, or struct?
Joan Venge
@Joan: Yes, if you specify the `Struct` attribute then the declaration will create a value type. Otherwise, it will create a class or an interface (depending on whether there is a constructor and any non-abstract member in the type declaration).
Tomas Petricek