自定义F#类型如何映射到CLR类型?

时间:2010-09-18 21:10:24

标签: c# f# type-systems

我不知道问题的标题是否清楚,但我想知道自定义F#类型的实际类型。

与C#类似,有值类型和引用类型。对于F#,是否存在一种管理类型系统的类型?

它们都是值类型(因为默认情况下它们是不可变的)吗?

或者是否存在与值/引用类型无关的全新类型?

任何信息都会有所帮助。

4 个答案:

答案 0 :(得分:12)

F#有各种类型。标准.NET类型(也存在于C#中),例如接口委托,将直接映射到相应的CLR表示。

您还可以使用Struct属性定义值类型(在这种情况下,您获得与C#struct对应的类型)和枚举喜欢这样:

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

type Enumeration = 
  | First = 1
  | Second = 2

其余的F#类型特定于F#,并且在CLR中没有任何标准表示。 F#编译器将它们编码为一个类(或几个类)。

  • 记录只是一个类,其属性对应于记录的字段。
  • 元组使用通用Tuple<...>类(.NET 4.0中的新增功能)表示

  • 功能值使用通用FSharpFunc<...>类型表示。这允许F#实现currying&amp;部分功能应用,所以有点棘手。例如,int -> int -> int将是FSharpFunc<int, FSharpFunc<int, int>>。该类型有一个Invoke方法,您可以使用该方法使用第一个参数调用它。 F#还会生成一个包含Invoke方法的派生类型,该方法采用所有参数,效率更高,并且大部分时间都在使用。

  • 歧视联合表示为具有抽象基类(与联合类型同名)的类层次结构,以及每个案例的子类。例如:

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

    这将创建一个抽象基类Shape和两个派生的具体类RectangleCircle(实际上,Shape类中的嵌套类)。这些派生类将包含存储案例属性所需的字段(例如矩形的位置)。

如果您想了解更多信息,可以查看Jomo Fisher的Adventures in F# series

答案 1 :(得分:3)

ECMA 335(CLI),第8.5.2节称为:值类型和引用类型

它们不是C#(唯一)概念。

答案 2 :(得分:2)

值和引用类型来自.NET,而不是C#。不是F#的专家,但我必须相信他们的类型是相同的,因为它是一流的.NET语言并且宣传与C#的互操作性。

此外,引用类型可以是不可变的(例如String),值类型可以是可变的(几乎所有在.NET中都是) - 这些与可变/不可变选择无关。

编辑:根据评论更正。

答案 3 :(得分:1)

你也有F#中的接口,类和结构 - 这些映射与其他CLR语言(如C#)一样,所以出于接口目的,你应该限制自己使用这些类型。

对于有区别的工会和记录,映射更复杂,如果你不是必须的话,那就不是你想要做的事情。