I'm trying to create an interpreter for a functional language in haskell (I'm new to the language). I'm creating what's probably a weird mix of minimalism and convenience - no abstract data types, but I want to provide the ability to make homogeneous lists.
So my basic variables  are data Datum = DatInt Int | DatDbl Double | DatBool Bool and I've realized I'm not at all sure how to represent homogeneous lists. Adding a constructor List Datum or something of the sort would make a heterogeneous list, and making a separate list for each type, i.e. ListInt [Int] | ListDbl [Double] would preclude lists of lists. 
What would be the best way to go about representing a homogeneous list?
Recall earlier that Haskell has many different kinds of types, such as * for value-containing types, [*] for type-level lists, etc. Haskell also has a special kind called Symbol from the module GHC.
One useful notion (whether you're going for sexy types or not) is that of a type tag. The non-sexy version is a lot easier to deal with.
data Tag = IntTag
         | DoubleTag
         | BoolTag
         | ListTag Tag
   deriving (Eq, Show)
Now your types are represented by these various tags. An Int is represented by IntTag. A list of Int is represented by ListTag IntTag.
Now you can represent type-annotated expressions something like this:
data Expr = IntLit Int
          | DoubleLit Double
          | BoolLit Bool
          | ListLit Tag [Expr]
-- Check that an expression is validly annotated
typeCheck :: Expr -> Maybe Tag
typeCheck IntLit{} = Just IntTag
...
typeCheck (ListLit tag els)
  | all good els = Just (ListTag tag)
  | otherwise = Nothing
  where
    good el = case typeCheck el of
                Nothing -> False
                Just res = res == tag
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With