Real World Haskell(2)[exercise4]

import Maybe (catMaybes)

---Exercise 4.1
safeHead :: [a] -> Maybe a
safeTail :: [a] -> Maybe [a]
safeLast :: [a] -> Maybe a
safeInit :: [a] -> Maybe [a]
   
safeFunc f [] = Nothing
safeFunc f xs = Just $ f xs

safeHead = safeFunc head
safeTail = safeFunc tail
safeLast = safeFunc last
safeInit = safeFunc init

---Exercise 4.2
splitWith :: (a -> Bool) -> [a] -> [[a]]
splitWith _ [] = []
splitWith p xs = helper $ break p xs
    where
      helper ([],rest) = (splitWith p (dropWhile p rest))
      helper (x,rest) = x : (splitWith p (dropWhile p rest))

---Exercise 4.3
   -- **(in Interact.hs)**
        -- myFunction = unlines . catMaybes . (map (safeHead . words)) . lines
        --     where safeHead [] = Nothing
        --           safeHead xs = Just $ head xs


---Exercise 4.4
transpose str = unlines $ loop $ lines str
    where
      loop xs | all null xs = []
              | otherwise = map head xs : (loop (map tail xs))

-- 大きさの違うものにも対応。
transpose2 str = unlines $ map catMaybes $ loop $ lines str
    where
      loop xs | all null xs = []
              | otherwise = es : (loop rest)
                  where
                    es = map safeHead xs
                    rest = catMaybes $ map safeTail xs

-- tranpose "hello\nworld\n" == "hw\neo\nlr\nll\nod\n" -- => True
-- transpose "123\n12\n1" -- => "111\n22*** Exception: Prelude.head: empty list
-- transpose2 "123\n12\n1" -- => "111\n22\n3\n"