F#中一个非常基本的类型检查失败了......为什么?

时间:2013-08-04 18:21:51

标签: f# f#-interactive f#-3.0

我写了这段代码

type Test =
    | Age of int
    | Name of string;;

let x = Age(10);;


if (x.GetType() = typeof<Test>) then printfn "true" else printfn "false";;

代码打印为false。但这让我感到困惑,因为不是Age of type Test?

另外,有没有更好的方法来比较F#中的类型.GetType() = typeof<>非常长。我试过:?,但我认为这是用于类型转换而不是比较类型。

3 个答案:

答案 0 :(得分:4)

答案很简单:

if (x :> obj) :? Test then printfn "true" else printfn "false"

这个问题是因为DUs的实现(使用内部类和标签)以及F#类型系统的限制(不承认实现)。

如您所见,x的类型为FSI_0001+Test+Age,而F#无法将其识别为Test的子类型。

答案 1 :(得分:2)

从规范中引用

  

编译的联合类型U具有:

     

·每个空联合案例C的一个CLI静态getter属性U.C   property获取一个代表每个这种情况的单例对象。

     

·每个非空联合案例C的一个CLI嵌套类型U.C。此类型   具有实例属性Item1,Item2 ....用于union的每个字段   case或单个实例属性如果只有一个字段,则为Item。   但是,只有一个案例的编译联合类型没有   嵌套类型。相反,联合类型本身扮演着案件的角色   类型。

我们看到Age是作为父DU的嵌套类型实现的。因此,您可以使用Type.GetNestedTypes获取DU的所有子类型,然后测试每个子类型以查看类型是否匹配。

答案 2 :(得分:-2)

  

但这让我感到困惑,因为它不是Color of Color?

没有类型ColorTest本身就是一种类型,因此它没有类型。所以你的问题是荒谬的。

也许你想问为什么答案是什么?如果是这样,那是F#当前选择在内部表示这些值的方式的结果。