-- | The Prelude defines the most common data types and functions for -- | us, but the LANGUAGE construct at the top of the page excludes the -- | normally automatically imported Prelude. Here we add back in what -- | we might need in this module. import Prelude (Show, IO, Int, String, putStrLn, ($), show, (++), (+), (-), (*)) -- | our own version of a list datatype data Lst a = NIL | Cons a (Lst a) deriving (Show) -- | our own version of a boolean datatype data Booly = Yep | Nope deriving (Show) -- | Returns true if an instance of @Lst@ is empty, false otherwise isEmpty :: Lst a -> Booly isEmpty NIL = Yep isEmpty _ = Nope {-| An example list of integers 1 - 4 -} ex01 :: Lst Int ex01 = Cons 1 (Cons 2 (Cons 3 (Cons 4 NIL))) {-| Doubles the input parameter -} dub :: Int -> Int dub n = n * 2 {-| Apply a function to eeach element in a list to produce a new list -} lstMap :: (a -> b) -> Lst a -> Lst b lstMap _ NIL = NIL lstMap f (Cons x xs) = Cons (f x) (lstMap f xs) {-| Makes a string of repeated strings -} makeStringOf :: String -> Int -> String makeStringOf _ 0 = "" makeStringOf s n = s ++ (makeStringOf s (n - 1)) {-| Fold for Lst -} lstFold :: (b -> a -> b) -> b -> Lst a -> b lstFold _ acc NIL = acc lstFold f acc (Cons x xs) = lstFold f (f acc x) xs {-| Get the length of a list by folding over the list with an accumulator function -} lstLen :: Lst a -> Int lstLen xs = lstFold (\acc _ -> 1 + acc) 0 xs main :: IO () main = do putStrLn $ "ex1 : " ++ (show ex01) putStrLn $ "ex1 length : " ++ (show (lstLen ex01)) putStrLn $ "doubled ex1 : " ++ (show (lstMap dub ex01)) putStrLn $ "histogram : " ++ (show (lstMap (makeStringOf "*") ex01))