# HG changeset patch # User Daichi TOMA # Date 1373067381 -32400 # Node ID 69e052c7ef6cc0b8e1ea779995a1f2b7cf085ec9 # Parent 3a7df492ae348c99567df3e456a04017cf4cfd41 fix diff -r 3a7df492ae34 -r 69e052c7ef6c haskell.html --- a/haskell.html Sat Jul 06 07:56:31 2013 +0900 +++ b/haskell.html Sat Jul 06 08:36:21 2013 +0900 @@ -264,7 +264,6 @@

簡単なプログラム

-

 {-# LANGUAGE OverloadedStrings #-}
 import Network.Wai
@@ -276,6 +275,7 @@
 
 main = run 3000 application
 
+

このソースコードを読み解いていきます。

@@ -323,6 +323,14 @@ run は、Port と Application を受け取って、IO () を返す関数だということが分かります。

+ IO () は IO モナドを表しています。 + I/O といった副作用を持つ処理を行う時に利用します。 +

+

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

+

Port は、Int の別名です。
別名などの定義は、:t ではみれないので、:i を使うとよいでしょう。
Haskellでは、関数は小文字、型名などは大文字で始まります。 @@ -330,7 +338,7 @@

- Application は、なんでしょうか? + Application

 ghci> :i Application
@@ -338,13 +346,16 @@
   Request -> ResourceT IO Response
 

- Monad に包まれていて少しわかりにくいですが、端的に言えば Request を受け取って Response を返す関数を表しています。 + Request を受け取って Response を返す関数を表しています。

- ResourceT は、リソースの解放を取り扱う Monad、 IO は、入出力を取り扱う Monad です。 + Response は 2つのモナドに包まれています。

- Haskell では、関数が副作用を持つことは許されませんが、IO アクションによって IO 操作を処理系に押し付けています。 + ResourceT は、IOのリソースの解放を安全に行うためのものです。 +

+

+ Haskell では、関数が副作用を持つことは許されませんが、IO モナドによって IO 操作を処理系に押し付けています。

@@ -364,14 +375,14 @@ main = run 3000 application

- 型情報を読むことでおおよそ分かったような気がしませんか! + 型情報から以下のことが分かります。

Port 番号と、Request を受け取って Response 返す関数を受け取る
run は IO () を返すので、外界に影響を与える

- 実際の動作としては、この関数 run は受け取った Port 番号で、Application を実行します。 + 実際の動作としては、この関数 run は受け取った Port 3000番で、Application を実行します。

次に、Application の実装を見ていきます。 @@ -389,6 +400,17 @@

まず引数で渡される Request は _ (Underscore) となっているので、使用していません。

+

+ return の後ろに付いている $ は、関数適用演算子といって括弧の数を減らすのに役たちます。 + 普通の関数適用は非常に優先順位が高いのですが、$ は最も低い優先順位を持ちます。 +

+

+ 下記の2つのコードは同じ結果になります。 +

+
+sum (map sqrt [1..130])
+sum $ map sqrt [1..130]
+
@@ -529,13 +551,13 @@ routeSetting = [([], index), (["hello"], hello), (["welcome","world"],world)] -notFound = do +notFound = responseLBS status404 [("Content-type", "text/html")] $ "404 - File Not Found" -index = do +index = responseLBS status200 [("Content-type", "text/html")] $ "index page" -hello = do +hello = responseLBS status200 [("Content-type", "text/html")] $ "hello, my name is Tom" -world = do +world = responseLBS status200 [("Content-type", "text/html")] $ "Welcome to Underground" main = run 3000 application @@ -618,16 +640,16 @@ いくつか定義してみます。

-notFound = do
+notFound =
     responseLBS status404 [("Content-type", "text/html")] $ "404 - File Not Found"
 
-index = do
+index =
     responseLBS status200 [("Content-type", "text/html")] $ "index page"
 
-hello = do
+hello =
     responseLBS status200 [("Content-type", "text/html")] $ "hello, my name is Tom"
 
-world = do
+world =
     responseLBS status200 [("Content-type", "text/html")] $ "Welcome to Underground"
 
@@ -651,13 +673,13 @@ routeSetting = [([], index), (["hello"], hello), (["welcome","world"],world)] -notFound = do +notFound = responseLBS status404 [("Content-type", "text/html")] $ "404 - File Not Found" -index = do +index = responseLBS status200 [("Content-type", "text/html")] $ "index page" -hello = do +hello = responseLBS status200 [("Content-type", "text/html")] $ "hello, my name is Tom" -world = do +world = responseLBS status200 [("Content-type", "text/html")] $ "Welcome to Underground" main = run 3000 application @@ -721,7 +743,7 @@

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