I would like to define data types hierarchically, such as:
data Cat = BigCat | SmallCat
data Animal = Cat | Dog
And then write a function that will take Animals as arguments, and write it with pattern matching like this:
bigger::Animal -> Animal -> Bool
bigger SmallCat BigCat = False
bigger BigCat SmallCat = True
bigger Dog Cat = True
bigger Cat Dog = False
The compiler complains. It doesn’t want to match the type Animal explicitely written in the function signature against the type Cat in the first and second lines of pattern matching. Why won’t haskell admit that a big cat or small cat is an animal?
You mix up types with their constructors. A type is something of which you can create variables. A type constructor is what you use to create such data. In you code,
data Animal = Cat | Dogdeclares a typeAnimalwith the two constructorsCatandDog. In the other line, you define a datatypeCat. This is no problem since types and constructors don’t share the same namespace.If you want to have an object of type
Catembedded in yourAnimal(if the constructorCatis used), you can add a field to the constructor:This means: “
Animalis a type that has two constructors,CatandDog.Cathas a field of typeCatandDoghas none.” If you want to create objects with the constructorCat, you have to pass an object of typeCatto it:If you want to match on an
Animal, you have to list all fields of the matched constructor. Compare a corrected version of your code:The
_denotes a don’t care – regardless of the object passed, this will always match.