ch04::RealWorldHaskell(1)
(p.88)ex.4-1
失敗する時はNothingを返せば良さそう。
-- ex.4-1 safeHead :: [a] -> Maybe a safeHead xs | null xs = Nothing | otherwise = Just (head xs) safeTail :: [a] -> Maybe [a] safeTail xs | null xs = Nothing | otherwise = Just (tail xs) safeLast :: [a] -> Maybe a safeLast xs | null xs = Nothing | otherwise = Just (last xs) safeInit :: [a] -> Maybe [a] safeInit xs | null xs = Nothing | otherwise = Just (init xs)
Main> head [] *** Exception: Prelude.head: empty list Main> safeHead [] Nothing Main> tail [] *** Exception: Prelude.tail: empty list Main> safeTail [] Nothing Main> last [] *** Exception: Prelude.last: empty list Main> safeLast [] Nothing Main> init [] *** Exception: Prelude.init: empty list Main> safeInit [] Nothing Main>
(p.89)ex.4-2
-- ex.4-2 splitWith :: (a -> Bool) -> [a] -> [[a]] splitWith _ [] = [] splitWith pred (x:xs) | not (pred x) = splitWith pred xs | otherwise = pre : (splitWith pred suf) where pre = takeWhile pred (x:xs) suf = dropWhile pred (x:xs)
Main> splitWith odd [0,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,4,2,0] [[1],[3,3,3],[5,5,5,5,5]] Main> splitWith even [0,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,4,2,0] [[0],[2,2],[4,4,4,4,],[6,4,2,0]]
何だかイケテない気がする、もっとスマートな解法があるかも。
(p.89)ex.4-3
-- file: InteractWith.hs -- 前提(CommandLineFramework) import System.Environment (getArgs) interactWith function inputFile outputFile = do input <- readFile input File 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 argument needed" -- myFunction = id myFunction = firstWord -- myFunctionにfirstWordを指定する -- ex.4-3 firstWord :: String -> String firstWord input = unlines (firstWordList (lines input)) firstWordList :: [String] -> [String] firstWordList [] = [] firstWordList (x:xs) | null (words x) = "" : firstWordList xs | otherwise = head (words x) : (firstWordList xs)
$ ghc --make InteractWith [1 of 1] Compiling Main ( InteractWith.hs, InteractWith.o) Linking InteractWith ... $ cat input.txt ex.4-3 test sample sample 1 2 3 bar baz foo bar baz $ ./InteractWith input.txt output.txt $ cat output.txt ex.4-3 sample 1 bar baz foo $
(p.89)ex.4-4
-- ex.4-4 -- (補助関数) -- 行の最大長を取得 maxLineLength :: [String] -> Int maxLineLength [] = 0 maxLineLength xs = maximun (map length xs) -- 文字列の長さが引数の値になるようスペース(' ')で埋める fillWithSpace :: Int -> String -> String fillWithSpace len xs | length xs >= len = xs | otherwise = fillWithSpace len (xs ++ " ") -- 引数分の空文字を持つリストを返す setBase :: Int -> [String] setBase 0 = [] setBase n = [] : setBase (n - 1) -- (ここから行列入れ替え処理) -- 行列を入れ替える change :: Int -> [String] -> [String] change n [] = setBase n change n (x:xs) = zipWith (:) x (change n xs) -- CommandLineFrameworkにchangeを渡す -- ※myFunctionにchangeRowAndColを指定 changeRowAndCol :: String -> String changeRowAndCol input = unlines (change maxLen filledList) where maxLen = maxLineLength (lines input) filledList = map (fillWithSpace maxLen) (lines input)
$ ghc --make InteractWith [1 of 1] Compiling Main ( InteractWith.hs, InteractWith.o) Linking InteractWith ... $ cat sample.txt Welcome to Ohr::Life. Let's learn Haskell Programming. $ ./InteractWith sample.txt out.txt $ cat out.txt WLH eea lts c'k ose m l ell e taP orr no O g h r r a : m : m L i i n f g e . . $
できた!