Подтвердить что ты не робот

Буквенный атрибут не работает

Прочитав ответ Криса на 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", хотя я думаю, что это не должно. Что я здесь не вижу?

4b9b3361

Ответ 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