文字属性不起作用

时间:2010-10-08 11:31:30

标签: f#

在阅读了Chris对F# - public literal的回复以及http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx的博文后,我不明白为什么以下内容无效:

[<Literal>]
let one = 1

[<Literal>]
let two = 2

let trymatch x =
    match x with
    | one -> printfn "%A" one
    | two -> printfn "%A" two
    | _ -> printfn "none"


trymatch 3

这保持打印“3”,虽然我认为不应该。我在这里看不到的是什么?

4 个答案:

答案 0 :(得分:23)

我认为文字必须是大写的。以下工作正常:

[<Literal>]
let One = 1
[<Literal>]
let Two = 2

let trymatch x =
    match x with
    | One -> printfn "%A" One
    | Two -> printfn "%A" Two
    | _ -> printfn "none"


trymatch 3

此外,如果你想要一个不错的通用解决方案而不使用文字,你可以像这样定义一个参数化的活动模式:

let (|Equals|_|) expected actual = 
  if actual = expected then Some() else None

然后写下

let one = 1
let two = 2

let trymatch x =
    match x with
    | Equals one -> printfn "%A" one
    | Equals two -> printfn "%A" two
    | _ -> printfn "none"

答案 1 :(得分:14)

其他答案是正确的 - 你必须用大写字母开始你的标识符。请参阅7.1.2 of the spec(命名模式)部分,其中指出:

  

如果long-ident是不以大写字符开头的单个标识符,则它始终被解释为变量绑定模式,并表示由模式绑定的变量

答案 2 :(得分:7)

此外,如果您不想使用大写文字,可以将它们放在模块中(此处命名为Const):

module Const =
    [<Literal>]
    let one = 1
    [<Literal>]
    let two = 2

let trymatch x =
    match x with
    | Const.one -> printfn "%A" Const.one
    | Const.two -> printfn "%A" Const.two
    | _ -> printfn "none"

trymatch 3

答案 3 :(得分:2)

不要问我为什么,但是当你写文字大写时它会起作用:

[<Literal>]
let One = 1
[<Literal>]
let Two = 2

let trymatch (x:int) =
    match x with
    | One -> printfn "%A" One
    | Two -> printfn "%A" Two
    | _ -> printfn "none"

trymatch 3