Literal Attribute not working

旧巷老猫 提交于 2019-12-06 18:56:45

问题


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 see here?


回答1:


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"



回答2:


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




回答3:


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



回答4:


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


来源:https://stackoverflow.com/questions/3890037/literal-attribute-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!