These are the first exercises of chapter 4.
Write your own “safe” definitions of the standard partial list functions, but make sure they never fail.
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 (x:[]) = Just x
safeLast (x:xs) = safeLast xs
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit (_:[]) = Just []
safeInit (x:xs) = Just (x : inner xs)
where inner [] = []
inner (_:[]) = []
inner (a:as) = a : inner as
Write a function splitWith that acts similarly to words but takes a predicate and a list of any type, and then splits its input list on every element for which the predicate returns False:
splitWith :: (a -> Bool) -> [a] -> [[a]]
splitWith p xs = split [[head xs]] (tail xs)
where split (x:xs) (y:ys) = if p y
then split (x:xs ++ [[y]]) ys
else case safeInit xs of
Just i -> split (x:i ++ [last xs ++ [y]]) ys
Nothing -> split [x ++ [y]] ys
split xs [] = xs
Using the command framework from the earlier section ‘A Simple Command-Line Framework’, write a program that prints the first word of each line of its input.
import System.Environment (getArgs)
interactWith function inputFile outputFile = do
input <- readFile inputFile
writeFile outputFile (function input)
main = mainWith myFunction
where mainWith function = do
args <- getArgs
case args of
[input,output] -> interactWith function input output
_ -> putStrLn "error: exactly two arguments needed"
-- replace "id" with the name of our function below
myFunction = firstWord
firstWord :: String -> String
firstWord s = unlines (firstWord (lines s))
where firstWord [] = []
firstWord (l:ls) = (head (words l)) : firstWord ls
Write a program that transposes the text in a file. For instance, it should convert “hello\nworld\n” to “hw\neo\nlr\nll\nod\n”.
rotated :: String -> String
rotated s = unlines (rotate (lines s))
where rotate [] = []
rotate xs = [heads xs] ++ rotate (rest xs)
heads [] = []
heads (x:xs) = head x : heads xs
rest [] = []
rest (x:xs) = if null (tail x)
then []
else [tail x] ++ rest xs