syd_sydの日記

2006-06-14

[]Data.ByteString

lambdaBotソースを読んでいたら、ネットワーク送信部分らしき

import qualified Data.ByteString.Char8 as P (pack, hPut, hPutStrLn)
:
:
            Just msg -> P.hPut h $ P.pack $ IRC.encodeMessage msg "\r"

という記述を発見 (IRC.hs, 250行目付近)。

hPut? Data.ByteString? … あった。 ?? しかし私のghc-6.4.2には入ってない。 ghcのトップから辿れるドキュメントには載ってない。GHC6.5からは入るのかな?GHC6.6〜らしい。

Haskell Communities and Activities Report

ついこの間出たらしい。4.6.3を読むと,ByteStringは http://www.cse.unsw.edu.au/~dons/fps.htmlが元になっていると。 newBinaryやSerTHを漁っていたので面食らいました。でもserializingとはまた別の話かもしれない?

とりあえずネットワーク周りはこれを使っておけば良さそう。

[]SerTHとData.ByteString

どちらもIOにはhPutBuf等が使われている。高速な文字列操作にはByteStringを、様々な型を簡単にserializationしたい時にはSerTHを使うのが良さそう。

SerTHは、Template Haskellによりserializeのためのインスタンス宣言(メソッドの定義)を簡略化することができる。

2006-06-13

[][] evaluate と return : 項の強制評価

Control.Exception.evaluate

evaluate :: a -> IO a

returnと似て非なるもの。渡された項を評価する。これが効いてくるのは、「無限に続く(止まらない) 計算」や「エラーを投げる計算」を食わせた時。

例:

do
  return $ 1 `div` 0 -- 0除算
  putStrLn "I'm still alive!"

I'm still alive!

となるのに対し*1

do
  Control.Exception.evaluate $ 1 `div` 0 -- 0除算
  putStrLn "I'm still alive!"

は 1/0が評価されて、

*** Exception: divide by zero

となる。

必ず評価する、という点ではseq と似てるけど、seq は第一引数を捨てるし、 evaluate は IOモナドを返す点で違う(本文参照)。 次のthrowとthrowIOの違いに似てる?

*1:return (1`div`0) >>= \_-> putStrLn "..." となり、遅延評価により除算されない。これに対し return (1`div`0) >>= \x-> putStrLn $ show x とやればputStrLnに必要なため1/0が評価され例外がraiseされる。