haskellでのバイナリデータの書き出し その2
バイナリデータの扱いを例として、モナドの使い方の練習を引き続き行っています。
work03$ 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. # バイナリのPutモナドの作成 Prelude> let tt1 = Data.Binary.Put.putWord8 68 Loading package array-0.4.0.1 ... linking ... done. Loading package deepseq-1.3.0.1 ... linking ... done. Loading package bytestring-0.10.0.2 ... linking ... done. Loading package containers-0.5.0.0 ... linking ... done. Loading package binary-0.5.1.1 ... linking ... done. Prelude> Data.Binary.Put.runPut tt1 "D" # バイナリのPutモナドの作成 2個目 Prelude> let tt2 = Data.Binary.Put.putWord8 69 Prelude> Data.Binary.Put.runPut tt2 "E" # モナドの合成 Prelude> let m = tt1 >> tt2 Prelude> Data.Binary.Put.runPut m "DE" # ファイルハンドラの作成 Prelude> let fileH = System.IO.openFile "./test01.bin" System.IO.WriteMode Prelude> :t fileH fileH :: IO GHC.IO.Handle.Types.Handle # Putモナドの中身の取り出し Prelude> let mm = Data.Binary.Put.runPut m Prelude> :t mm mm :: Data.ByteString.Lazy.Internal.ByteString # ファイルへの書き出し (なんでエラーになるの??) Prelude> Data.ByteString.Lazy.hPut fileH mm <interactive>:12:27: Couldn't match expected type `GHC.IO.Handle.Types.Handle' with actual type `IO GHC.IO.Handle.Types.Handle' In the first argument of `Data.ByteString.Lazy.hPut', namely `fileH' In the expression: Data.ByteString.Lazy.hPut fileH mm In an equation for `it': it = Data.ByteString.Lazy.hPut fileH mm # do表記で書き直し。 Prelude> do {f <- fileH;Data.ByteString.Lazy.hPut f mm} Prelude> :q Leaving GHCi. # 出力ファイルの確認 work03$ hexdump test01.bin 0000000 44 45 0000002 work03$ perl -le 'print 16*4+4' 68 work03$ perl -le 'print 16*4+5' 69
do表記を使わずにバインドで記述したかったので、しばし悩んだ後、下記で行けました。
work03$ 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> let tt1 = Data.Binary.Put.putWord8 70 Loading package array-0.4.0.1 ... linking ... done. Loading package deepseq-1.3.0.1 ... linking ... done. Loading package bytestring-0.10.0.2 ... linking ... done. Loading package containers-0.5.0.0 ... linking ... done. Loading package binary-0.5.1.1 ... linking ... done. Prelude> let tt2 = Data.Binary.Put.putWord8 71 Prelude> let tt3 = Data.Binary.Put.putWord8 72 Prelude> let m = tt1 >> tt2 >> tt3 Prelude> let mmm = Data.Binary.Put.runPut m Prelude> mmm "FGH" Prelude> let fileH = System.IO.openFile "./test02.bin" System.IO.WriteMode Prelude> fileH >>= (\x ->Data.ByteString.Lazy.hPut x mmm) Prelude> :q Leaving GHCi. work03$ hexdump test02.bin 0000000 46 47 48 0000003 work03$