2014年2月13日木曜日

開発環境

Real World Haskell―実戦で学ぶ関数型言語プログラミング(Bryan O'Sullivan (著)、 John Goerzen (著)、 Don Stewart (著)、山下 伸夫 (翻訳)、伊東 勝利 (翻訳)、株式会社タイムインターメディア (翻訳)、オライリージャパン)の9章(入出力事例研究: ファイルシステム検索ライブラリ)、9.7(走査方法の制御)の練習問題 1.を解いてみる。

その他参考書籍

練習問題 1.

コード(BBEdit, Emacs)

ControlledVisit.hs

{-# OPTIONS -Wall -Werror #-}
module ControlledVisit where

import System.Directory (Permissions, getDirectoryContents, getPermissions,
                         getModificationTime, searchable)
import System.IO (IOMode(..), openFile, hClose, hFileSize)
-- System.Timeは非推奨
import Data.Time.Clock (UTCTime)
import System.FilePath ((</>))
import Control.Exception (handle, bracket, SomeException)
import Control.Monad (liftM, forM)

main :: IO ()
main = do
    infos1 <- traverse id "../"
-- アルファベットの逆順にするためにreverseを渡す
    infos2 <- traverse reverse "../"
    putStrLn "id--------------------------------------"
    mapM_ print $ map infoPath infos1
    putStrLn "reverse---------------------------------"
    mapM_ print $ map infoPath infos2

data Info = Info { infoPath :: FilePath,
                   infoPerms :: Maybe Permissions,
                   infoSize :: Maybe Integer,
                   infoModTime :: Maybe UTCTime} deriving (Eq, Ord, Show)

getInfo :: FilePath -> IO Info
getInfo path = do
    perms <- maybeIO (getPermissions path)
    size <- maybeIO (bracket (openFile path ReadMode) hClose hFileSize)
    modified <- maybeIO (getModificationTime path)
    return (Info path perms size modified)

maybeIO :: IO a -> IO (Maybe a)
maybeIO act = handle nothing (Just `liftM` act)

nothing :: SomeException -> IO (Maybe a)
nothing _ = return Nothing

traverse :: ([Info] -> [Info]) -> FilePath -> IO [Info]
traverse order path = do
    names <- getUsefulContents path
    contents <- mapM getInfo (path:map (path </>) names)
    liftM concat $ forM (order contents) $ \info -> do
        if isDirectory info && infoPath info /= path
        then traverse order (infoPath info)
        else return [info]


getUsefulContents :: FilePath -> IO [String]
getUsefulContents path = do
    names <- getDirectoryContents path
    return (filter (`notElem` [".", ".."]) names)

isDirectory :: Info -> Bool
isDirectory = maybe False searchable . infoPerms

入出力結果(Terminal, runghc)

$ runghc ControlledVisit.hs 
id--------------------------------------
"../"
"../blog.html"
"../CC.hs"
"../ch03"
"../ch03/Intersperse.hs"
"../ch03/Tree.hs"
"../ch05"
"../ch05/Main.hi"
"../ch05/Main.hs"
"../ch05/Main.o"
"../ch05/Prettify.hs"
"../ch05/PrettyJSON.hs"
"../ch05/PutJSON.hs"
"../ch05/simple"
"../ch05/SimpleJSON.hi"
"../ch05/SimpleJSON.hs"
"../ch05/SimpleJSON.o"
"../ch08"
"../ch08/Glob.hs"
"../ch08/GlobRegex.hs"
"../ch09"
"../ch09/BetterPredicate.hs"
"../ch09/ControlledVisit.hs"
"../exercises.hs"
"../GrahamScan.hs"
"../InteractWith"
"../InteractWith.hi"
"../InteractWith.hs"
"../InteractWith.o"
"../mypretty"
"../mypretty/JSONClass.hs"
"../output.txt"
"../quux.txt"
"../SafeList.hs"
"../Sample.hs"
"../temp.txt"
"../WC.hs"
reverse---------------------------------
"../WC.hs"
"../temp.txt"
"../Sample.hs"
"../SafeList.hs"
"../quux.txt"
"../output.txt"
"../mypretty/JSONClass.hs"
"../mypretty"
"../InteractWith.o"
"../InteractWith.hs"
"../InteractWith.hi"
"../InteractWith"
"../GrahamScan.hs"
"../exercises.hs"
"../ch09/ControlledVisit.hs"
"../ch09/BetterPredicate.hs"
"../ch09"
"../ch08/GlobRegex.hs"
"../ch08/Glob.hs"
"../ch08"
"../ch05/SimpleJSON.o"
"../ch05/SimpleJSON.hs"
"../ch05/SimpleJSON.hi"
"../ch05/simple"
"../ch05/PutJSON.hs"
"../ch05/PrettyJSON.hs"
"../ch05/Prettify.hs"
"../ch05/Main.o"
"../ch05/Main.hs"
"../ch05/Main.hi"
"../ch05"
"../ch03/Tree.hs"
"../ch03/Intersperse.hs"
"../ch03"
"../CC.hs"
"../blog.html"
"../"
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> reverse ["A", "B", "a", "b"]
["b","a","B","A"]
Prelude> :quit 
Leaving GHCi.
$

大文字小文字の区別が出来てないのが気になったから、コマンド「ls」でオプション「-f(ソート)」を指定して表示してみる。

入出力結果(Terminal)

$ ls -f ../
.  ch05  InteractWith output.txt WC.hs
..  ch08  InteractWith.hi quux.txt
blog.html ch09  InteractWith.hs SafeList.hs
CC.hs  exercises.hs InteractWith.o Sample.hs
ch03  GrahamScan.hs mypretty temp.txt
$

大文字小文字の区別がされてないみたいだから、システムによるのかなぁ。

0 コメント:

コメントを投稿