View
4.544
Download
5
Category
Preview:
DESCRIPTION
走马观花—— Haskell Web 开发
Citation preview
——走马观花 Haskell Web开发
黄毅 http://www.yi-programmer.com/ yi.codeplayer@gmail.com
About me
● CPP(静 ) → Python(动 ) → Haskell(静 )● 专业 Python● 业余 Haskell
前情提要
● 一门 20多年依然冷门的语言的简单介绍
● 微线程模型并发处理的示例程序
● “ ”一种对 流式处理 的强大抽象
● 一个常数内存占用的 HTTP代理服务器的实现
● “ ”一种类型安全的 宏 ,并用它创建 DSL的例子
你将会了解到:
So,Why Haskell?
Quest for Certain Knowledge
of Programming
•纯,函数式(抽象!抽象!抽象!)
•命令式(显式的副作用管理)
•强大的静态类型系统(避免逻辑矛盾!)
虚的部分
实在一点,
针对Web开发,
Haskell能提供什么?
一、微线程和高并发
server <- listenOn (PortNumber 3000)
forever $ do
(client, h, p) <- accept server
hSetBuffering client NoBuffering
forkIO $ forever $ do
request <- hGetLine client
hPrintf client "%s from %s:
%d\n" request h (toInteger p)
二、 Iteratee针对流式数据处理的抽象
http://www.haskell.org/haskellwiki/Enumerator_and_iteratee
示例: A http proxy server runs in constant memory
http://github.com/yihuang/webproxy-yesod
状态机
requestLine :: Parser Request
requestLine = do
method <- P.takeWhile1 isToken <* char8 ' '
uri <- P.takeWhile1 (/=32) <* char8 ' '
version <- httpVersion <* endOfLine
...
状态机组合!
data Stream a = EOF | Chunks [a]
data Iteratee a b = Continue (Stream a → Step a b) | Yield b (Stream a) | Error String
data Enumerator a b = Iteratee a b → Iteratee a b
祭代码 状态机抽象
祭代码 Proxy Application
fetch :: Request IO -> (Status -> Headers -> Iteratee..) -> IO afetch req f = withManager $ \m -> run_ $ http req f m
getIndexR = do req <- liftIO $ parseUrl url sendWaiResponse $ ResponseEnumerator $ fetch req
简单 benchmark
● 300M数据文件, 100并发,恒定 25M RES
DSL for web framework
Template Haskell
● Run haskell at compile time
● Imagine type safe lisp macro
URL Route
mkYesod "Simple" [parseRoutes|
/ HomeR GET
/static StaticR GET
/article ArticleR GET POST
/article/#Int ArticleDetailR GET
|]
Templating
[|hamlet|
<div .section >
<h3>#{title}
<p>#{content}
|]
Widgets ( EDSL)
dateTimeField name = do
addScriptRemote “...”
addDateTimeCss “...”
toWidget [hamlet|<input ... |]
autoCompleteField name = do
addScriptRemote “...”
addDateTimeCss “...”
toWidget [hamlet|<input ... |]
myForm = do
[hamlet|<form ...|]
DateTimeField “date”
autoCompleteField “tag”
Widgets result
<script datetime.js
<script autocomplete.js
…
<link datetime.css
<link autocomplete.css
…
<input ...
Thanks!
Recommended