# HG changeset patch # User Daichi TOMA # Date 1373059451 -32400 # Node ID 50842df0402f4a1d6d6a5abbcd7a74e1a4ed2244 # Parent 2b869930dcfcb2709ca0a4bfbbbb85140518e518 add IORef diff -r 2b869930dcfc -r 50842df0402f haskell.html --- a/haskell.html Sat Jul 06 05:19:32 2013 +0900 +++ b/haskell.html Sat Jul 06 06:24:11 2013 +0900 @@ -243,6 +243,7 @@

Pong benchmark (req/s) + Preliminary Warp Cross-Language Benchmarks

@@ -476,7 +477,7 @@ Routing

- 次に単純な Routing を行う Web Site 実装してみたいと思います。 + 次に単純な Routing を行うサイトを実装してみたいと思います。

http://localhost:3000/ の後の URL の Path によって 出力する結果を変更してみます。 @@ -688,6 +689,79 @@ http://localhost:3000/hogehoge

+ +
+

+ Counter +

+

+ 最後に、Counter の実装を行なってみたいと思います。 +

+

+ アクセスするたびに、Count がインクリメントされていくようなサイトを作成します。 +

+

+ ここでは、Thread-safe な State である Data.IORef を用います。 +

+
+ +
+

+ 変数の更新はできなかったんじゃ? +

+

+ Haskell では、変数の更新のような副作用を持つ処理は基本的に許されていません。 +

+

+ そのため、IO モナドという限られた範囲でのみ行えるようになっています。 +

+

+ IOモナドは中身に直接触ることのできない抽象データ型です。 + 状態を外から触ることを禁止することで参照透過性を保っています。 +

+

+ また、Haskell は遅延評価ですが、初期化などIOでは実行順序が重要になってきます。 + IO モナドのbindを利用して、計算の実行順序を保証します。 +

+
+ +
+

+ Data.IORefの使い方 +

+

+ IOモナドは中身に直接触ることはできません。 +

+

+ IOモナドからデータを手に入れる唯一の方法は <- を使うことです。
+ <- を使うことで、純粋なものと不純なものをきっちりと分けています。 +

+

+ 変更する際も、modifyIORefなどの関数を利用します。 +

+
+ +
+

+ Data.IORefの使い方 +

+
+-- IORef Int という型のデータを作製する
+counter <- newIORef 0
+
+-- データの更新を atomic に行う
+-- atomicModifyIORef には、更新したい IORef a 型の変数と、
+-- IORef が持つ値を受け取って 
+-- ( 更新後の値, 戻り値にしたい値 ) というタプルを返す関数を渡す
+incCount:: IORef a -> IO a
+incCount counter = atomicModifyIORef counter (\c -> (c+1, c))
+
+-- 現在のデータの値を受け取る
+currentNum <- readIORef counter
+
+

+
+

そして気づくことなど