开发者

Literal Attribute not working

开发者 https://www.devze.com 2023-01-19 09:58 出处:网络
After reading Chris\' answer to F# - public literal and the blog post at http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx I don\'t get why the following is not work

After reading Chris' answer to F# - public literal and the blog post at http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx I don't get why the following is not working:

[<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

This keeps printing "3", although I think it shouldn't. What is it that I don't s开发者_开发知识库ee here?


I think that literals need to be Uppercase. The following works fine:

[<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

In addition, if you want a nice general solution for this without using literals, you can define a parameterized active pattern like this:

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

And then just write

let one = 1
let two = 2

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


The other answers are right - you must start your identifier with an uppercase letter. See section 7.1.2 of the spec (Named Patterns), which states that:

If long-ident is a single identifier that does not begin with an uppercase character then it is always interpreted as a variable-binding pattern and represents a variable that is bound by the pattern


Also if you don't want to have Uppercase literals you can put them in a module (here named 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


Don't ask me why, but it works when you write your literals uppercase:

[<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
0

精彩评论

暂无评论...
验证码 换一张
取 消