Mercurial > hg > Members > toma > osc2013
changeset 4:3a7df492ae34
add discription for counter
author | Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 06 Jul 2013 07:56:31 +0900 |
parents | 50842df0402f |
children | 69e052c7ef6c |
files | haskell.html |
diffstat | 1 files changed, 140 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/haskell.html Sat Jul 06 06:24:11 2013 +0900 +++ b/haskell.html Sat Jul 06 07:56:31 2013 +0900 @@ -264,6 +264,7 @@ <h3> 簡単なプログラム </h3> + <p> <pre> {-# LANGUAGE OverloadedStrings #-} import Network.Wai @@ -275,7 +276,6 @@ main = run 3000 application </pre> - <p> このソースコードを読み解いていきます。 </p> <p> @@ -335,7 +335,7 @@ <pre> ghci> :i Application type Application = - Request -> Control.Monad.Trans.Resource.ResourceT IO Response + Request -> ResourceT IO Response </pre> <p> Monad に包まれていて少しわかりにくいですが、端的に言えば Request を受け取って Response を返す関数を表しています。 @@ -396,7 +396,7 @@ responseLBS とは? </h3> <pre> -Prelude Network.Wai.Handler.Warp Network.Wai Network.HTTP.Types> :t responseLBS +ghci> :t responseLBS responseLBS :: Status -> ResponseHeaders @@ -515,7 +515,7 @@ 作成するプログラム全容 </h3> <p> - <a href="https://gist.github.com/amothic/5933808">Source Code</a> + <a href="https://gist.github.com/amothic/5933808">routes.hs</a> <pre> application request = return $ routes $ pathInfo request @@ -637,7 +637,7 @@ 完成! </h3> <p> - <a href="https://gist.github.com/amothic/5933808">Source Code</a> + <a href="https://gist.github.com/amothic/5933808">routes.hs</a> <pre> application request = return $ routes $ pathInfo request @@ -764,6 +764,141 @@ <article> <h3> + では、このIORefを使ってCounterを作りましょう! + </h3> + <p> +<pre> +-- 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 +</pre> + </p> + </article> + + <article class="smaller"> + <h3> + プログラム全容 + </h3> + <p> + <a href="https://gist.github.com/amothic/5937576">counter.hs</a> +<pre> +{-# LANGUAGE OverloadedStrings #-} +import Network.Wai +import Network.HTTP.Types (status200) +import Network.Wai.Handler.Warp (run) +import Control.Monad.Trans (liftIO, lift) +import Data.IORef (newIORef, atomicModifyIORef) +import Data.ByteString.Lazy.UTF8 (fromString) + +application counter request = do + count <- lift $ incCount counter + return $ responseLBS status200 [("Content-type", "text/html")] $ + fromString $ show count + +incCount counter = atomicModifyIORef counter (\c -> (c+1, c)) + +main = do + counter <- newIORef 0 + run 3000 $ application counter +</pre> + </p> + </article> + + <article> + <h3> + main + </h3> + <p> + mainでは、counterの初期化を行なっています。 + </p> + <p> + それをrunとdo構文で糊付けしています。 + </p> +<pre> +main = do + counter <- newIORef 0 + run 3000 $ application counter +</pre> + </article> + + <article> + <h3> + application + </h3> + <p> + applicationでは、引数をひとつ増やして、初期化されたIORefを受け取れるようにしています。 + </p> + <p> + また、incCountを、ResourceTのモナド内に持ち込むためliftを行なっています。 + </p> + <p> + incCountでは、atomicModifyIORefを使って、counterをインクリメントしています。 + </p> +<pre> +application counter request = do + count <- lift $ incCount counter + return $ responseLBS status200 [("Content-type", "text/html")] $ + fromString $ show count + +incCount counter = atomicModifyIORef counter (\c -> (c+1, c)) +</pre> + </article> + + <article class="smaller"> + <h3> + 完成! + </h3> + <p> + <a href="https://gist.github.com/amothic/5937576">counter.hs</a> +<pre> +{-# LANGUAGE OverloadedStrings #-} +import Network.Wai +import Network.HTTP.Types (status200) +import Network.Wai.Handler.Warp (run) +import Control.Monad.Trans (liftIO, lift) +import Data.IORef (newIORef, atomicModifyIORef) +import Data.ByteString.Lazy.UTF8 (fromString) + +application counter request = do + count <- lift $ incCount counter + return $ responseLBS status200 [("Content-type", "text/html")] $ + fromString $ show count + +incCount counter = atomicModifyIORef counter (\c -> (c+1, c)) + +main = do + counter <- newIORef 0 + run 3000 $ application counter +</pre> + </p> + </article> + + <article> + <h3> + 実行 + </h3> + <p> + <a href="http://localhost:3000/">http://localhost:3000/</a> + </p> + <p> + アクセスするたびに表示される数字がインクリメントされていくはずです。 + </p> + <p> + Chromeだと、毎回faviconにアクセスされるせいで、countが+2されていきます… + </p> + </article> + + <article> + <h3> そして気づくことなど </h3> <p>