Unit 9: Datatypes
Enumerated types
As the name suggests,
an enumerated type in Haskell is introduced by listing its members.
Say you want to make use of the type
Day
which contains the days of the week:
data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat
deriving (Eq,Ord,Enum,Show)
Note that not only the type Day
must start with an uppercase letter,
but also its members.
The deriving
clause ensures that the identity and ordering relations
can be applied to members of Day
, that they can be converted to integers
and that they can be printed to the terminal.
If Enum
is included in the deriving
clause,
the functions fromEnum
and toEnum
are available, although they cannot be used directly:
fromDay :: Day -> Int
fromDay = fromEnum
toDay :: Int -> Day
toDay = toEnum
Functions can be defined that make use of user-defined types just as they can with built-in types:
weekend :: Day -> Bool
weekend Sun = True
weekend Sat = True
weekend _ = False
Composite types
data Tag = Tagi Int | Tagb Bool
deriving (Eq,Ord,Show)
isInt :: Tag -> Bool
isInt (Tagi _ ) = True
isInt (Tagb _ ) = False
Recursive types
data Btree a = Tip a | Bin (Btree a) (Btree a)
deriving (Eq,Ord,Show)
tree1 = Bin (Tip 1) (Bin (Tip 6) (Tip 5))
size :: Btree a -> Int
size (Tip _) = 1
size (Bin s t) = size s + size t
depth :: Btree a -> Int
depth (Tip _) = 0
depth (Bin s t) = 1 + max (depth s) (depth t)
flatten :: Btree a -> [a]
flatten (Tip x) = [x]
flatten (Bin xt yt) = flatten xt ++ flatten yt
inodes :: Btree a -> Int
inodes (Tip _) = 0
inodes (Bin xt yt) = 1 + inodes xt + inodes yt
maxBtree :: Ord a => Btree a -> a
maxBtree (Tip x) = x
maxBtree (Bin xt yt) = max (maxBtree xt) ( maxBtree yt)
It is possible to defines functions on binary trees analogous to the map
and fold
functions defined on lists:
mapBtree :: (a -> b) -> Btree a -> Btree b
mapBtree f (Tip x) = Tip (f x)
mapBtree f (Bin xt yt)
= Bin (mapBtree f xt) (mapBtree f yt)
foldBtree :: (a -> b) -> (b -> b -> b) -> Btree a -> b
foldBtree f g (Tip x) = f x
foldBtree f g (Bin xt yt)
= g (foldBtree f g xt) (foldBtree f g yt)
Using the catamorphism,
foldBtree
it is possible to define all the functions on Btree
that were defined previously and also mapBtree
:
size1 :: Btree a -> Integer
size1 = foldBtree (const 1) (+) where const x y = x
depth1 :: Btree a -> Integer
depth1 = foldBtree (const 0) op
where op m n = 1 + max m n; const x y = x
flatten1 :: Btree a -> [a]
flatten1 = foldBtree wrap (++) where wrap x = [x]
maxBtree1 :: Ord a => Btree a -> a
maxBtree1 = foldBtree id max
mapBtree1 :: (a -> b) -> Btree a -> Btree b
mapBtree1 f = foldBtree (Tip . f) Bin
© Antoni Diller (22 September 2021)