在阅读了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”,虽然我认为不应该。我在这里看不到的是什么?
答案 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