haskell超初心者勉強会11
DESCRIPTION
TRANSCRIPT
Haskell超初心者勉強会11回2013/7/29
Monday, July 29, 13
今日は「すごいHaskell」本9章 もっと入力、もっと出力•入力ストリームからの読み込み•ファイルの読み書き•コマンドライン引き数•ランダム性• bytestring
Monday, July 29, 13
入力ストリーム
• getContents :: IO String•一度に全てを読み込まない。メモリを食いつぶさない。文字列(文字リスト)を遅延評価する。
import Data.Charmain = do contents <- getContents putStr $ map toUpper contents
Monday, July 29, 13
ファイルの読み込み
• hFoo は Handle を引数に取る関数• hGetContents は stdin の代わりに handle から読み込む
•遅延評価
import System.IOmain = do handle <- openFile “baabaa.txt” ReadMode contents <- hGetContents handle putStr contents hClose handle
Monday, July 29, 13
ファイルの読み込みwithFile
•開いて、関数実行して、閉じる•例外の場合でも確実に閉じる
import System.IOmain = do withFile “baabaa.txt” ReadMode $ \handle do contents <- hGetContents handle putStr contents
Monday, July 29, 13
Control.Exception のbracket
•何かして、関数実行して、何かする
withFile’ :: FilePath -> IOMode -> (Handle -> IO a)withFile’ name mode f = bracket (openFile name mode) (\handle -> hClose handle) (\handle -> f handle)
Monday, July 29, 13
Control.Exception のbracketOnError
•何かして、関数実行して、例外のときだけ何かする
•例:一時ファイルを開いて、処理する、例外のときだけ一時ファイルを消す
Monday, July 29, 13
その他の h
• h じゃない版と同じ挙動(handle を取る意外は)
hClosehGetContentshGetLinehPutStrhPutStrLnhGetChar
Monday, July 29, 13
readFile
• readFile :: FilePath -> IO String•開いて読んで閉じる
import System.IOmain = do contents <- readFile “baabaa.txt” putStr contents
Monday, July 29, 13
writeFile/appendFile
• readFile :: FilePath -> String -> IO ()•開いて書いて閉じる
import System.IOmain = do contents <- readFile “baabaa.txt” writeFile “baabaacaps.txt” (map toUpper contents)
Monday, July 29, 13
コマンドライン引数
• System.Environment の getArgs/getProgName
import System.Environmentimport Data.Listmain = do args <- getArgs progName <- getProgName putStrLn “The arguments are:” mapM putStrLn args putStrLn “The Program name is:” putStrLn progName
Monday, July 29, 13
ランダム性
• System.Random モジュール• RandomGen型クラス:ランダム性の源として使える型
• Random型クラス: ランダムな値として使える型
random :: (RandomGen g, Random a) => g -> (a,g)mkStdGen :: Int -> StdGen
Monday, July 29, 13
乱数のテスト
• random はピュアな関数•乱数を続けて発生させるときは戻り値の RandomGen を次の乱数源として使う
> random (mkStdGen 100) :: (Int, StdGen)(-3650871090684229393,693699796 2103410263)> random (mkStdGen 100) :: (Int, StdGen)(-3650871090684229393,693699796 2103410263)
Monday, July 29, 13
randoms
•ランダム値の無限リストを返す• RandomGen は返さない
randoms :: (RandomGen g, Random a) => g -> [a]
Monday, July 29, 13
randomR
•ある範囲の乱数を返す• (下限, 上限) -> (ジェネレータ) ->(乱数, 新ジェネレータ)
randomR :: (RandomGen g, Random a) => (a, a) -> g -> (a, g)
Monday, July 29, 13
getStdGen
•グローバル乱数ジェネレータを返す•プログラム実行毎に違う値• 1実行中は同じ値を返す
getStdGen :: IO StdGen
Monday, July 29, 13
newStdGen
•グローバル乱数ジェネレータを更新•新しい乱数ジェネレータを返す
newStdGen :: IO StdGen
Monday, July 29, 13
thunk
•サンク(thunk)=遅延された計算 •リストの未評価の部分は thunk•文字列(文字リスト)は thunk が沢山なので遅い
Monday, July 29, 13
bytestring
•リストに似たデータ構造•要素は 1 byteのサイズ固定
Monday, July 29, 13
正格 vs 遅延• 正格 bytestring (Data.ByteString)• thunk なし• 最初のバイトを評価する時、全体を評価• 遅延 bytestring (Data.ByteString.Lazy)• 64KB chunk 毎に評価される• 64KB は L2 cache にフィットする良いサイズ
Monday, July 29, 13
pack/unpack
•リストと相互変換•Word8 は 8 bits unsigned int
pack :: [Word8] -> ByteStringunpack :: ByteString -> [Word8]
> import qualified Data.ByteString.Lazy as B> let x = B.pack [99, 97, 110]> x“can”> B.unpack x[99, 97, 110]
Monday, July 29, 13
fromChunks
•正格ByteStringのリスト ->遅延ByteString
Monday, July 29, 13
bytestring モジュールの関数
• Data.List と似た関数• head, tail, init, null, length, map, foldl, foldr, concat, takeWhile, filter など
• http://hackage.haskell.org/package/bytestring/
• System.IO と似た関数• readFile :: FilePath -> IO ByteString など
Monday, July 29, 13
文字列用プログラムを bytestring 向けに
1.修飾付き import する
2.対応する関数の前にモジュール名を付け足す
• まず文字列で書いて、性能が足りなかったら bytestring を試すのがオススメ
Monday, July 29, 13