Caseless Underscore

It is a convention that the compiler will not warn about unused variables that begin with an underscore. In Haskell 98, an underscore also counts as a lower case letter meaning that you cannot start type, class, or data constructors with it.


Make underscore 'caseless' meaning when deciding whether a name is a constructor or not, look through underscores. so

data Foo = Foo | _Bar  -- ^ _Bar possibly unused

will be valid.

we can either treat identifiers containing only underscores as lowercase names or invalid depending on how important the ability to obfuscate code is to us. (or a composite number of them being a variable and a prime number of them being a constructor if we really really want to allow obfuscated code :) )

The leading underscore convention is not only useful as a way to suppress warnings, but as a form of documentation that we expect a name to be unused so being able to use it in these cases would be helpful.

Change to the Report

Change the productions for varid and conid in section 2.4 to

varid -> ({ _ } small {small | large | digit | _ | ' })<reservedid>
conid -> { _ } large {small | large | digit | _ | ' }

In the above, there are no underscore-only identifiers, but single underscore is a reservedid.

For full backward compatibility, we would need to allow underscore-only varids, changing the first production to:

varid -> ({ _ } ( _ | small {small | large | digit | _ | ' }))<reservedid>


Caseless underscore is implemented in nhc98 by default, H'98 behaviour requires the -underscore option.

Last modified 9 years ago Last modified on Apr 13, 2008 5:18:54 PM