2015-03-31 137 views
2

用户定义类型为内置类型,如int和字符串,注释他们在一个函数的方法是这样的:混乱在F#

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

这是一种注解:

let testFunction (x:int) = x * x 

但在该行:

let test (NewType a)= a * 2 

这不是一个类型标注。它通过模式匹配被称为分解。模式匹配也可以应用于函数参数,如你的例子。它的作用是解开包含在NewType中的int值,并将其绑定到a值。这就是为什么,因为它是在int值完成,而不是在NewType

最后一行也是一种注解,你可以做一个乘法:

let test (a:NewType) = a * 2 

因为乘法是通过推断它不工作默认为int,注释表明a类型为NewType,这就是为什么您会收到此错误消息。你必须像你一样打开它let test (a:NewType) = a * 2

+0

哦是的。谢谢你指出。当我查看repl中的签名时,它是有意义的。它返回类型'NewType = | NewType的int'。谢谢。 – himekami 2015-03-31 08:05:34

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).