I have a little problem while creating data types.
I have two data types, Football and Tennis
data Football a = Football
{ players :: Players a
, Stadium :: Stadium a
}
data Tennis a = Tennis
{ players1 :: Players a
, Stadium1 :: Stadium a
}
And I want to create an other datatype Sport using as a constructor the datatype football and tennis
data Sport a = Football a | Tennis a
and I get the following error, multiple declarations of Football I don't understand what I am doing wrong.
Best regards
Your idea is correct in spirit but Haskell uses tagged unions (also called "discriminated unions", "disjoint unions", "variants", and "sum types"). This means you need an additional tag to determine if Sport is constructed with Football or if it is constructed with Tennis.
data Sport = SportFootball Football | SportTennis Tennis
These tags are known in Haskell as data constructors. That is, this defines a constructor SportFootball :: Football -> Sport
and a constructor SportTennis :: Tennis -> Sport
.
Suppose Haskell did not require this extra tag, then what would be this type?
data UntaggedInt = Int | Int
An untagged union should have the property (x | x) = x
and so this must be equivalent to:
data UntaggedInt = Int
Whereas with tagged unions we can define:
data TaggedInt = This Int | That Int
That is, tagged unions are not idempotent.
Also consider something else which happens without constructors. Suppose we have a definition such as:
data UntaggedLists = String | [String]
And now we are tasked with finding the type of the expression "hello world"
. Should the type be String
or UntaggedLists
? Then suppose we have another similar definition:
data AnotherUntaggedLists = String | [String]
Is it true that UntaggedLists
and AnotherUntaggedLists
are equal types?
These are not unanswerable questions, but it does demonstrate a profound systematic difference between having tags and not.
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