Haskell: Similar data constructors and boiler plate

65 views Asked by At

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?

1

There are 1 answers

0
amalloy On BEST ANSWER

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