Algebraic datatypes

data TList = Void | Cons Integer TList
 
tlength :: TList -> Integer
tlength Void = 0
tlength (Cons i l) = 1 + tlength l
 
 
data PList a = PVoid | PCons a (PList a)
 
plength :: PList a -> Integer
plength PVoid = 0
plength (PCons i l) = 1 + plength l
 
toHaskell :: PList a -> [a]
toHaskell PVoid = []
toHaskell (PCons i l) = i:(toHaskell l)
 
fromHaskell :: [a] -> PList a
fromHaskell [] = PVoid
fromHaskell (x:xs) = PCons x (fromHaskell xs)
 
 
fromm :: [a] -> PList a
fromm = foldr PCons PVoid
 
{-
===========================================
 
      Sorting 
 
===========================================
 
The signature for sorting is:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
 
data Ordering = LT | EQ | GT
 
-}
byLength :: [String] -> [String]
byLength = sortBy op
                where op s1 s2
                            | length s1 > length s2 = GT
                            | length s1 == length s2 = EQ
                            | otherwise = LT
 
{-
===========================================
 
      Modeling exceptions in Haskell
 
===========================================
 
What does head return if the list is empty?
It may return a value, instead of simply crashing.
-}
 
data Result a = Error String |  -- a value of type (Result a) is an error, or
                Value a         -- an actual value, wrapped by the data constructor Value
                deriving Show
 
phead :: [a] -> Result a
phead (x:xs) = Value x
phead [] = Error "Empty list"
 
-- Write a function which extracts the first element from a list of strings
-- the function returns an error if one string is empty.
-- Example:
{-
 
extract ["Matei", "Mihai", ""] = Error "Emptystring found"
extract ["Matei", "Mihai"] = Value ['M', 'M']
 
-}
extract = (foldr op (Value [])) . (map phead)
            where op (Value e) (Value acc) = Value (e:acc)
                  op (Error _) _ = Error "Emptystring found"
                  op (Value _) (Error m) = Error m