Search code examples
haskellparameterized-types

Haskell optional type parameter


In haskell, how do you define an optional type parameter:

data Car a b c = Car { company :: a
                     , model :: b
                     , year :: c  
                     }
-- I want to return this type if `c` is not provided
data Car a b = Car { company :: a  
                   , model :: b
                   }

In above, I wanna have have an optional type c and based on whether it's provided or not return a slightly different type. How do I do this? Am I doing this totally wrong?


Solution

  • Depending on what exactly you're asking, there are different approaches I'm familiar with. But first of all it's not clear to me that you want those types to be parameterized. i.e. I suspect what you really want is something like:

    data Car = Car { company :: Company
                   , model :: String
                   , year :: Int  
                   }
    

    In particular it seems unlikely that you would need separate representations for the year. If that's the case, then the answer to your question (how to make the year optional is:

    data Car = Car { company :: Company
                   , model :: String
                   , year :: Maybe Int -- N.B. Maybe  
                   }
    

    If you're really asking about having a parameterized type which is optional then you can do something like this:

    data Foo a = Foo Int Char a
    

    Then you can use this as Foo () when you wish to treat it as "a Foo without the last parameter". You can further make a newtype wrapper around it if you want.

    newtype FooWithoutA = FooWithoutA (Foo ())
    

    Since the unit type () has just a single value this indicates there's nothing of interest in that field.


    Aside: You also might be interested in reading http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/ which will give you a sense of why different ways of structuring your data are equivalent, among other insights.