module RwhChap4 where import Data.Char import Data.List -- page 84 -- ex. 1 safeHead :: [a] -> Maybe a safeHead [] = Nothing safeHead (x:xs) = Just x safeTail :: [a] -> Maybe [a] safeTail [] = Nothing safeTail (x:xs) = Just xs safeLast :: [a] -> Maybe a safeLast [] = Nothing safeLast xall@(x:xs) = Just (last xall) safeInit :: [a] -> Maybe [a] safeInit [] = Nothing safeInit xall@(x:xs) = Just (init xall) -- ex. 2 splitWith :: (a -> Bool) -> [a] -> [[a]] splitWith _ [] = [] splitWith p xs = filter (\l -> not $ null l) $ reverse $ swHelper p xs [] [] where swHelper p [] acc lst = reverse acc ++ lst swHelper p (x:xs) acc lst | not $ p x = swHelper p xs [] [(reverse acc)]++lst | otherwise = swHelper p xs (x:acc) lst -- ex. 3 -- done, see file chapter-4-p84-3.hs -- ex. 4 -- done, see file chapter-4-p84-4.hs -- pages 97-99 -- ex. 1. done asIntFold1 :: String -> Int asIntFold1 = foldl (\x c -> x*10 + digitToInt c) 0 -- ex. 2. done asIntFold2 :: String -> Int asIntFold2 xx@(x:xs) | x == '-' = - asIntFold2 xs | x == '+' || isSpace x = asIntFold2 xs | otherwise = foldl (\x c -> x*10 + digitToInt c) 0 xx -- ex. 3. done asIntFold3 :: String -> Int asIntFold3 xx@(x:xs) | (x == '-' || x == '+' || isSpace x) && null xs = error "Bad argument" | x == '-' = - asIntFold3 xs | x == '+' || isSpace x = asIntFold3 xs | length xx > 9 = error "Overflow" | otherwise = foldl (\x c -> x*10 + digitToInt c) 0 xx -- ex. 4. done data Ei = ErrMessage String | Intgr Int deriving Show asIntEither :: String -> Ei asIntEither xx@(x:xs) | (x == '-' || x == '+' || isSpace x) && null xs = ErrMessage "Bad argument" | x == '-' = let r = asIntEither xs in case r of (Intgr i) -> Intgr (- i) _ -> r | x == '+' || isSpace x = asIntEither xs | length xx > 9 = ErrMessage "Overflow" | otherwise = Intgr (foldl (\x c -> x*10 + digitToInt c) 0 xx) -- ex. 5 & 6. done concatFold :: [[a]] -> [a] concatFold [] = [] concatFold xs = foldl (\ lst x -> lst ++ x) [] xs -- ex. 7 takeWhileRec :: (a -> Bool) -> [a] -> [a] takeWhileRec f [] = [] takeWhileRec f xs = reverse $ tHelper f xs [] where tHelper fp [] lst = lst tHelper fp (x:xs) lst | fp x = tHelper fp xs (x:lst) | otherwise = lst