I am learning Haskell from learnyouahaskell.com. I am having trouble understanding type constructors and data constructors. For example, I don\'t really understand the diffe
As others pointed out, polymorphism isn't that terrible useful here. Let's look at another example you're probably already familiar with:
Maybe a = Just a | Nothing
This type has two data constructors. Nothing
is somewhat boring, it doesn't contain any useful data. On the other hand Just
contains a value of a
- whatever type a
may have. Let's write a function which uses this type, e.g. getting the head of an Int
list, if there is any (I hope you agree this is more useful than throwing an error):
maybeHead :: [Int] -> Maybe Int
maybeHead [] = Nothing
maybeHead (x:_) = Just x
> maybeHead [1,2,3] -- Just 1
> maybeHead [] -- None
So in this case a
is an Int
, but it would work as well for any other type. In fact you can make our function work for every type of list (even without changing the implementation):
maybeHead :: [t] -> Maybe t
maybeHead [] = Nothing
maybeHead (x:_) = Just x
On the other hand you can write functions which accept only a certain type of Maybe
, e.g.
doubleMaybe :: Maybe Int -> Maybe Int
doubleMaybe Just x = Just (2*x)
doubleMaybe Nothing= Nothing
So long story short, with polymorphism you give your own type the flexibility to work with values of different other types.
In your example, you may decide at some point that String
isn't sufficient to identify the company, but it needs to have its own type Company
(which holds additional data like country, address, back accounts etc). Your first implementation of Car
would need to change to use Company
instead of String
for its first value. Your second implementation is just fine, you use it as Car Company String Int
and it would work as before (of course functions accessing company data need to be changed).