Real World Haskell
実戦で学ぶ関数型言語プログラミング
(オライリージャパン)
Bryan O'Sullivan (著) John Goerzen (著)
Don Stewart (著)
山下 伸夫 (翻訳) 伊東 勝利 (翻訳)
株式会社タイムインターメディア (翻訳)
開発環境
- OS X Mavericks - Apple(OS)
- BBEdit - Bare Bones Software, Inc., Emacs (Text Editor)
- Haskell (純粋関数型プログラミング言語)
- GHC (The Glasgow Haskell Compiler) (処理系)
- The Haskell Platform (インストール方法、モジュール等)
Real World Haskell―実戦で学ぶ関数型言語プログラミング(Bryan O'Sullivan (著)、 John Goerzen (著)、 Don Stewart (著)、山下 伸夫 (翻訳)、伊東 勝利 (翻訳)、株式会社タイムインターメディア (翻訳)、オライリージャパン)の9章(入出力事例研究: ファイルシステム検索ライブラリ)、9.5(ファイルサイズを安全に決める)、9.5.1(獲得 - 使用 - 開放サイクル)の練習問題 1.を解いてみる。
その他参考書籍
- すごいHaskellたのしく学ぼう!(オーム社) Miran Lipovača(著)、田中 英行、村主 崇行(翻訳)
- プログラミングHaskell (オーム社) Graham Hutton(著) 山本 和彦(翻訳)
練習問題 1.
そのままだと、次のようなエラーになるのでとりあえずコードを修正。
No instance for (GHC.Exception.Exception e0) arising from a use of `handle' The type variable `e0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance GHC.Exception.Exception Control.Exception.Base.NestedAtomically -- Defined in `Control.Exception.Base' instance GHC.Exception.Exception Control.Exception.Base.NoMethodError -- Defined in `Control.Exception.Base' instance GHC.Exception.Exception Control.Exception.Base.NonTermination -- Defined in `Control.Exception.Base' ...plus 7 others In the expression: handle (\ _ -> return Nothing) (return (Just 10)) In an equation for `getFileSize': getFileSize path = handle (\ _ -> return Nothing) (return (Just 10))
コード(BBEdit, Emacs)
BetterPredicate.hs
{-# OPTIONS -Wall -Werror #-} import Control.Exception (handle, bracket, SomeException) import System.IO (IOMode(..), openFile, hClose, hFileSize) getFileSize :: FilePath -> IO (Maybe Integer) getFileSize path = handle nothing $ bracket (openFile path ReadMode) hClose $ \h -> do size <- hFileSize h hClose h return (Just size) nothing :: SomeException -> IO (Maybe Integer) nothing _ = return Nothing
入出力結果(Terminal, インタプリタghci)
$ 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> :load BetterPredicate.hs [1 of 1] Compiling Main ( BetterPredicate.hs, interpreted ) Ok, modules loaded: Main. *Main> getFileSize "BetterPredicate.hs" Just 432 *Main> getFileSize "abcde" Nothing *Main> :quit Leaving GHCi. $
bracketとhandleを呼ぶ順番は重要。逆の順序にすると、先に例外を取り除いてしまい、ゴミになったファイルをハンドルにたまったままにしてしまう。
0 コメント:
コメントを投稿