走马观花— Haskell Web 开发

Post on 13-May-2015

4.544 views 5 download

description

走马观花—— Haskell Web 开发

Transcript of 走马观花— Haskell Web 开发

——走马观花 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!