2013年11月18日月曜日

開発環境

初めてのコンピュータサイエンス(Jennifer CampbellPaul GriesJason MontojoGreg Wilson(著)長尾 高弘(翻訳))の8章(ファイル処理)、8.8(練習問題)、3.をHaskellで解いてみる。

その他参考書籍

8.8(練習問題)、3.

コード(BBEdit)

Sample.hs

{-# OPTIONS -Wall -Werror #-}

main :: IO ()
main = do
    contents <- readFile "weather.txt"
    putStrLn "テキストの内容"
    putStrLn contents
    let a = lines contents
    mapM_ print $ map (\s -> string2weather s fieldCols) a
    putStrLn "ラッパー関数"
    mapM_ print $ map (\s -> string2weatherWrap s (length s)) a

type Date = (Int, Int, Int)
type Latitude = (Int, Int, Int)
type Longitude = (Int, Int, Int)
type Data = (Double, Double, Double)

fieldCols :: [[Int]]
fieldCols = [[4, 2, 2], [2, 2, 2], [2, 2, 2], [6, 6, 6]]

fieldStarts :: [[Int]]
fieldStarts = [[0, 4, 6], [8, 10, 12], [14, 16, 18], [20, 26, 32]]

fieldStarts2Cols :: [[Int]] -> Int -> [[Int]]
fieldStarts2Cols [] _ = []
fieldStarts2Cols ([a, b, c]:[]) n = [[b - a, c - b, n - c]]
fieldStarts2Cols ([a, b, c]:[d, e, f]:ns) n =
    [b - a, c- b, d - c]:fieldStarts2Cols ([d, e, f]:ns) n
fieldStarts2Cols _ _ = []

string2weatherWrap :: String -> Int -> (Date, Latitude, Longitude, Data)
string2weatherWrap s n = string2weather s $ fieldStarts2Cols fieldStarts n

string2weather :: String -> [[Int]] -> (Date, Latitude, Longitude, Data)
string2weather s fields =
    let dateField :: [Int]
        dateField = fields !! 0
        latitudeField :: [Int]
        latitudeField = fields !! 1
        longtitudeField :: [Int]
        longtitudeField = fields !! 2
        dataField :: [Int]
        dataField = fieldCols !! 3
        [a, b, c, d] = map sum [dateField, latitudeField, longtitudeField,
                                dataField]
    in (string2date (take a s) dateField,
        string2latitude (take b . drop a $ s) latitudeField,
        string2longtitude (take c . drop (a + b) $ s) longtitudeField,
        string2data (take d. drop (sum [a, b, c]) $ s) dataField)

string2date :: String -> [Int] -> Date
string2date s field =
    let [a, b, c] = map (field !!) [0..2]
    in (read (take a s) :: Int,
        read (take b . drop a $ s) :: Int,
        read (take c . drop (a + b) $ s) :: Int)

string2latitude :: String -> [Int] -> Latitude
string2latitude s field =
    let [a, b, c] = map (field !!) [0..2]
    in (read (take a s) :: Int,
        read (take b . drop a $ s) :: Int,
        read (take c . drop (a + b) $ s) :: Int)

string2longtitude :: String -> [Int] -> Longitude
string2longtitude s field =
    let [a, b, c] = map (field !!) [0..2]
    in (read (take a s) :: Int,
        read (take b . drop a $ s) :: Int,
        read (take c . drop (a + b) $ s) :: Int)

string2data :: String -> [Int] -> Data
string2data s field =
    let [a, b, c] = map (field !!) [0..2]
    in (read (take a s) :: Double,
        read (take b . drop a $ s) :: Double,
        read (take c . drop (a + b) $ s) :: Double)

入出力結果(Terminal, runghc)

$ runghc Sample.hs
テキストの内容
20070503241737385605100.00121.3016.370
20070503241737385605100.00121.3016.370

((2007,5,3),(24,17,37),(38,56,5),(100.0,121.3,16.37))
((2007,5,3),(24,17,37),(38,56,5),(100.0,121.3,16.37))
ラッパー関数
((2007,5,3),(24,17,37),(38,56,5),(100.0,121.3,16.37))
((2007,5,3),(24,17,37),(38,56,5),(100.0,121.3,16.37))
$

{-# OPTIONS -Wall -Werror #-}を記述してるから、細かく型を指定(:: Double)しないと警告がいっぱい出た。慣れるまでは{-# OPTIONS -Wall -Werror #-}の記述を消さずに細かく型を指定していくことに。

0 コメント:

コメントを投稿