Буквенный атрибут не работает
Прочитав ответ Криса на 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", хотя я думаю, что это не должно. Что я здесь не вижу?
Ответы
Ответ 1
Я думаю, что литералы должны быть "верхними". Следующее прекрасно работает:
[<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"
Ответ 2
Другие ответы верны - вы должны завести свой идентификатор с помощью прописной буквы. См. Раздел 7.1.2 спецификации (Именованные шаблоны), который гласит, что:
Если long-ident - это один идентификатор, который не начинается с символа верхнего регистра, он всегда интерпретируется как шаблон привязки переменных и представляет переменную, связанную с шаблоном
Ответ 3
Также, если вы не хотите иметь литералы в верхнем регистре, вы можете поместить их в модуль (здесь называется 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
Не спрашивайте меня, почему, но это работает, когда вы пишете свои литералы в верхнем регистре:
[<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