F# Zen – The Literal Attribute

 

When pattern matching it is easy to forget that you are capturing a new value instead of matching against an existing one. Take this function for example:

 let E  = 2.718281828459
let PI = 3.141592653589

// Ooops - this captures a value
let isConstant x =
    match x with
    | PI
    | E -> true
    | _ -> false

The right way to write this code is to use the [<Literal>] attribute. This tells the F# compiler to treat this value as a constant literal which, among other things, enables it to be used with pattern matching.

 [<Literal>]
let E  = 2.718281828459
[<Literal>]
let PI = 3.141592653589

// This matches against the literal value
let isConstant x =
    match x with
    | PI
    | E -> true
    | _ -> false

Comments

  • Anonymous
    October 03, 2008
    PingBack from http://www.easycoded.com/f-zen-%e2%80%93-the-literal-attribute/

  • Anonymous
    October 03, 2008
    Is this a valid code? I tried your code at FSI (version 1.9.6.2). However, when define E or PI (decimal type) it become error. error FS0191: Values marked with 'LiteralAttribute' must currently be simple integer, character, Boolean, string or floating point constants.

  • Anonymous
    October 04, 2008
    Nope, you're right. I've updated my post - I'll follow up with the design team to see if that's the behavior we want. Thanks for pointing this out!

  • Anonymous
    October 05, 2008
    Hi Chris, i follow yor blog regularly..this is working good only for what... igeta said in his comments...also just to let you know it is not working for me in MONO, the problem is even after i used literal attribute...it is still capturing the value of the parameter passed to the function. Thanks for the great blog.  

  • Anonymous
    October 05, 2008
    As I understand, the problem is that there are no proper System.Decimal literals on the CLR level. C# fakes it (use ILDASM to see how), so probably F# should, too...