Атрибут Literal не работает - PullRequest
17 голосов
/ 08 октября 2010

Прочитав ответ Криса на F # - общедоступный литерал и пост в блоге на 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 ]

23 голосов
/ 08 октября 2010

Я думаю, что литералы должны быть в верхнем регистре.Следующее прекрасно работает:

[<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"
14 голосов
/ 08 октября 2010

Остальные ответы верны - вы должны начать свой идентификатор с заглавной буквы.См. Раздел 7.1.2 спецификации (Именованные шаблоны), в котором говорится:

Если long-identifier - это один идентификатор, который не начинается с символа в верхнем регистре, тогда онвсегда интерпретируется как шаблон привязки переменной и представляет переменную, связанную шаблоном

7 голосов
/ 08 октября 2010

Также, если вы не хотите иметь заглавные литералы, вы можете поместить их в модуль (здесь он называется 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
2 голосов
/ 08 октября 2010

Не спрашивайте меня, почему, но это работает, когда вы пишете прописные буквы:

[<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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...