on master help sign in
Add a literate Haskell program, README.lhs
commitc1fdc97e8a644f143652449501dac6c985aac2a9 authorSimon Hengel <simon.hengel@wiktory.org> dateTue 20 Apr 2010, 13:39 (16 years ago) parent15dba58
4 files changed+238
README README.lhs+111 README.md+106 lhs2md.sh+21
READMEdeleted

No changes to the content.

README.lhsnew file+111
@@ -0,0 +1,111 @@
1+WAI: Web Application Interface
2+==============================
3+
4+Getting started
5+---------------
6+
7+You want a minimal example? Here it is!
8+
9+> {-# LANGUAGE OverloadedStrings #-}
10+> import Network.Wai
11+> import Network.Wai.Enumerator (fromLBS)
12+> import Network.Wai.Handler.SimpleServer (run)
13+>
14+> app :: Application
15+> app _ = return Response
16+> { status = Status200
17+> , responseHeaders = [(ContentType, "text/plain")]
18+> , responseBody = Right $ fromLBS "Hello, Web!"
19+> }
20+>
21+> main :: IO ()
22+> main = do
23+> putStrLn $ "http://localhost:8080/"
24+> run 8080 app
25+
26+Put that code into a file named _hello.hs_ and install [wai] and
27+[wai-extra] from Hackage:
28+
29+ cabal install wai wai-extra
30+
31+Run it:
32+
33+ runhaskell hello.hs
34+
35+Point your browser to:
36+
37+ http://localhost:8080/
38+
39+
40+Serving static content
41+----------------------
42+
43+We can modify our previous example to serve static content. For this
44+create a file named _index.html_:
45+
46+ <p>Hello, Web!</p>
47+
48+Now we redefine `responseBody` to refer to that file:
49+
50+> app2 :: Application
51+> app2 _ = return index
52+>
53+> index = Response
54+> { status = Status200
55+> , responseHeaders = [(ContentType, "text/html")]
56+> , responseBody = Left "index.html"
57+> }
58+
59+
60+Basic dispatching
61+-----------------
62+
63+An `Application` maps `Request`s to `Response`s:
64+
65+ ghci> :info Application
66+ type Application = Request -> IO Response
67+
68+Depending on the path info provided with each `Request` we can serve
69+different `Response`s:
70+
71+> app3 :: Application
72+> app3 request = case pathInfo request of
73+> "/" -> return index
74+> "/raw/" -> return plainIndex
75+> _ -> return notFound
76+>
77+> plainIndex = Response
78+> { status = Status200
79+> , responseHeaders = [(ContentType, "text/plain")]
80+> , responseBody = Left "index.html"
81+> }
82+>
83+> notFound = Response
84+> { status = Status404
85+> , responseHeaders = [(ContentType, "text/plain")]
86+> , responseBody = Right $ fromLBS "404 - Not Found"
87+> }
88+
89+
90+Doing without overloaded strings
91+--------------------------------
92+
93+For the sake of efficiency, WAI uses the [bytestring] package. We used
94+GHCs [overloaded strings] to almost hide this fact. But we can easily do
95+without. What follows is a more verbose definition of `notFound`, that
96+works without GHC extensions:
97+
98+ import qualified Data.ByteString.Char8 as B8
99+ import qualified Data.ByteString.Lazy.Char8 as LB8
100+
101+ notFound = Response
102+ { status = Status404
103+ , responseHeaders = [(ContentType, B8.pack "text/plain")]
104+ , responseBody = Right $ fromLBS $ LB8.pack "404 - Not Found"
105+ }
106+
107+
108+ [wai]: http://hackage.haskell.org/package/wai
109+ [wai-extra]: http://hackage.haskell.org/package/wai-extra
110+ [overloaded strings]: http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#overloaded-strings
111+ [bytestring]: http://hackage.haskell.org/package/bytestring
README.mdnew file+106
@@ -0,0 +1,106 @@
1+<!-- Generated from README.lhs, do not modify this file! -->
2+WAI: Web Application Interface
3+==============================
4+
5+Getting started
6+---------------
7+
8+You want a minimal example? Here it is!
9+
10+ {-# LANGUAGE OverloadedStrings #-}
11+ import Network.Wai
12+ import Network.Wai.Enumerator (fromLBS)
13+ import Network.Wai.Handler.SimpleServer (run)
14+
15+ app :: Application
16+ app _ = return Response
17+ { status = Status200
18+ , responseHeaders = [(ContentType, "text/plain")]
19+ , responseBody = Right $ fromLBS "Hello, Web!"
20+ }
21+
22+ main :: IO ()
23+ main = do
24+ putStrLn $ "http://localhost:8080/"
25+ run 8080 app
26+
27+Put that code into a file named _hello.hs_ and install [wai] and [wai-extra] from Hackage:
28+
29+ cabal install wai wai-extra
30+
31+Run it:
32+
33+ runhaskell hello.hs
34+
35+Point your browser to:
36+
37+ http://localhost:8080/
38+
39+
40+Serving static content
41+----------------------
42+
43+We can modify our previous example to serve static content. For this create a file named _index.html_:
44+
45+ <p>Hello, Web!</p>
46+
47+Now we redefine `responseBody` to refer to that file:
48+
49+ app2 :: Application
50+ app2 _ = return index
51+
52+ index = Response
53+ { status = Status200
54+ , responseHeaders = [(ContentType, "text/html")]
55+ , responseBody = Left "index.html"
56+ }
57+
58+
59+Basic dispatching
60+-----------------
61+
62+An `Application` maps `Request`s to `Response`s:
63+
64+ ghci> :info Application
65+ type Application = Request -> IO Response
66+
67+Depending on the path info provided with each `Request` we can serve different `Response`s:
68+
69+ app3 :: Application
70+ app3 request = case pathInfo request of
71+ "/" -> return index
72+ "/raw/" -> return plainIndex
73+ _ -> return notFound
74+
75+ plainIndex = Response
76+ { status = Status200
77+ , responseHeaders = [(ContentType, "text/plain")]
78+ , responseBody = Left "index.html"
79+ }
80+
81+ notFound = Response
82+ { status = Status404
83+ , responseHeaders = [(ContentType, "text/plain")]
84+ , responseBody = Right $ fromLBS "404 - Not Found"
85+ }
86+
87+
88+Doing without overloaded strings
89+--------------------------------
90+
91+For the sake of efficiency, WAI uses the [bytestring] package. We used GHCs [overloaded strings] to almost hide this fact. But we can easily do without. What follows is a more verbose definition of `notFound`, that works without GHC extensions:
92+
93+ import qualified Data.ByteString.Char8 as B8
94+ import qualified Data.ByteString.Lazy.Char8 as LB8
95+
96+ notFound = Response
97+ { status = Status404
98+ , responseHeaders = [(ContentType, B8.pack "text/plain")]
99+ , responseBody = Right $ fromLBS $ LB8.pack "404 - Not Found"
100+ }
101+
102+
103+ [wai]: http://hackage.haskell.org/package/wai
104+ [wai-extra]: http://hackage.haskell.org/package/wai-extra
105+ [overloaded strings]: http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#overloaded-strings
106+ [bytestring]: http://hackage.haskell.org/package/bytestring
lhs2md.shnew file+21
@@ -0,0 +1,21 @@
1+#!/bin/sh
2+#
3+# Convert a literate Haskell program (README.lhs) to GitHub Flavored
4+# Markdown (README.md).
5+#
6+# For more on GitHub Flavored Markdown see:
7+#
8+# http://github.github.com/github-flavored-markdown/
9+#
10+
11+# add a disclaimer
12+echo '<!-- Generated from README.lhs, do not modify! -->' > README.md
13+
14+cat README.lhs | \
15+
16+ # GFM does not ignore line breaks in paragraphs, so we remove them
17+ perl -0777 -pe 's/([]a-zA-Z,.`])\n([[a-zA-Z`])/\1 \2/g' | \
18+
19+ # convert Bird-style literate Haskell to Markdown code blocks
20+ perl -pe 's/^> / /' | \
21+ perl -pe 's/^>$//' >> README.md