Search code examples
haskellconstructoraccessor

Haskell: Similar data constructors and boiler plate


I have a type constructor Token and all of its data constructor take an Int (the position where this token was encountered in the input) and maybe some payload:

data Token = EmptyToken Int   -- just position
    | ValueToken Int Int      -- position and integer payload
    | NameToken Int String    -- position and string payload

When I want to obtain the position from a token, I end up with this quite cumbersome code:

position :: Token -> Int
position (EmptyToken position)   = position
position (ValueToken position _) = position
position (NameToken  position _) = position

This boiler plate makes me think that I am approaching the whole topic from the wrong direction.

What is the correct (or recommended) way to encode a data with some shared properties (like position) and some properties which are not shared?


Solution

  • Factor out the duplication in your data types just as you would your functions. Here's one way:

    data Positioned a = Positioned Int a
    data TokenData = Empty
                   | Value Int
                   | NameToken String
    
    type Token = Positioned TokenData