====== 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