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 (5)

  1. igeta says:

    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.

  2. ChrSmith says:

    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!

  3. rockstars369 says:

    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.  

  4. int19h says:

    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…

Skip to main content