对f#中用户定义类型的困惑

时间:2015-03-31 07:18:04

标签: types f#

对于像int和string这样的内置类型,在函数中注释它们的方法是这样的:

let testFunction (x:int) = x * x

但是对于用户定义的类型,使用它们的方式是不同的。如下所示:

type NewType = NewType of int

let test (NewType a)= a * 2

但是如果我按照以下方式放置它,则intepreter给我不匹配类型错误(int vs NewType):

let test (a:NewType) = a * 2

为什么?

2 个答案:

答案 0 :(得分:2)

这是一种类型注释:

let testFunction (x:int) = x * x

但是在行中:

let test (NewType a)= a * 2

这不是类型注释。它通过模式匹配称为分解。模式匹配也可以应用于函数参数,如示例中所示。它的作用是展开int中包含的NewType值并将其绑定到a值。这就是为什么你可以进行乘法运算,因为它是在int值而非NewType

上完成的

最后一行也是一个类型注释:

let test (a:NewType) = a * 2

它不起作用,因为默认情况下会将乘法推断为int,并且注释表明a类型属于NewType,这就是为什么你会得到此错误消息。你必须像let test (a:NewType) = a * 2

那样展开它

答案 1 :(得分:2)

您将模式匹配与类型注释混淆。您的第二个示例使用了正确的类型注释:

let test (a:NewType) = a * 2

不幸的是,这意味着您无法在没有模式匹配的情况下访问类型构造函数的int参数来提取它,如下所示:

let test (a:NewType) =
    match a with
    | NewType x -> x * 2

第一个适用于您的案例不是使用类型注释,而是模式匹配作为参数的一部分,因此您尝试访问的值 已经给出了一个名称,并且不需要进一步的模式匹配。如果你的类型有这样的多个模式,

type NewType = NewType of int
             | OtherType of float

并且您尝试使用模式而不是类型注释以第一种方式编写代码,您会看到一条警告,指出您的模式匹配不完整:

> let testcode (NewType a) = a * 2;;                  

  let testcode (NewType a) = a * 2;;
  --------------^^^^^^^^^

warning FS0025: Incomplete pattern matches on this expression. For example, 
the value 'OtherType (_)' may indicate a case not covered by the pattern(s).