走马观花— Haskell Web 开发

25
—— 走马观花 Haskell Web 开发 黄毅 http://www.yi-programmer.com/ [email protected]

description

走马观花—— Haskell Web 开发

Transcript of 走马观花— Haskell Web 开发

Page 1: 走马观花— Haskell Web 开发

——走马观花 Haskell Web开发

黄毅 http://www.yi-programmer.com/ [email protected]

Page 2: 走马观花— Haskell Web 开发

About me

● CPP(静 ) → Python(动 ) → Haskell(静 )● 专业 Python● 业余 Haskell

Page 3: 走马观花— Haskell Web 开发

前情提要

● 一门 20多年依然冷门的语言的简单介绍

● 微线程模型并发处理的示例程序

● “ ”一种对 流式处理 的强大抽象

● 一个常数内存占用的 HTTP代理服务器的实现

● “ ”一种类型安全的 宏 ,并用它创建 DSL的例子

你将会了解到:

Page 4: 走马观花— Haskell Web 开发

So,Why Haskell?

Page 5: 走马观花— Haskell Web 开发

Quest for Certain Knowledge

of Programming

Page 6: 走马观花— Haskell Web 开发

•纯,函数式(抽象!抽象!抽象!)

•命令式(显式的副作用管理)

•强大的静态类型系统(避免逻辑矛盾!)

虚的部分

Page 7: 走马观花— Haskell Web 开发

实在一点,

针对Web开发,

Haskell能提供什么?

Page 8: 走马观花— Haskell Web 开发

一、微线程和高并发

Page 9: 走马观花— Haskell Web 开发

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)

Page 10: 走马观花— Haskell Web 开发
Page 11: 走马观花— Haskell Web 开发

二、 Iteratee针对流式数据处理的抽象

http://www.haskell.org/haskellwiki/Enumerator_and_iteratee

Page 12: 走马观花— Haskell Web 开发

示例: A http proxy server runs in constant memory

http://github.com/yihuang/webproxy-yesod

Page 13: 走马观花— Haskell Web 开发
Page 14: 走马观花— Haskell Web 开发

状态机

Page 15: 走马观花— Haskell Web 开发

requestLine :: Parser Request

requestLine = do

method <- P.takeWhile1 isToken <* char8 ' '

uri <- P.takeWhile1 (/=32) <* char8 ' '

version <- httpVersion <* endOfLine

...

状态机组合!

Page 16: 走马观花— Haskell Web 开发

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

祭代码 状态机抽象

Page 17: 走马观花— Haskell Web 开发

祭代码 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

Page 18: 走马观花— Haskell Web 开发

简单 benchmark

● 300M数据文件, 100并发,恒定 25M RES

Page 19: 走马观花— Haskell Web 开发

DSL for web framework

Page 20: 走马观花— Haskell Web 开发

Template Haskell

● Run haskell at compile time

● Imagine type safe lisp macro

Page 21: 走马观花— Haskell Web 开发

URL Route

mkYesod "Simple" [parseRoutes|

/ HomeR GET

/static StaticR GET

/article ArticleR GET POST

/article/#Int ArticleDetailR GET

|]

Page 22: 走马观花— Haskell Web 开发

Templating

[|hamlet|

<div .section >

<h3>#{title}

<p>#{content}

|]

Page 23: 走马观花— Haskell Web 开发

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”

Page 24: 走马观花— Haskell Web 开发

Widgets result

<script datetime.js

<script autocomplete.js

<link datetime.css

<link autocomplete.css

<input ...

Page 25: 走马观花— Haskell Web 开发

Thanks!