Hi Haskell
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Hi Haskell

  • 2,850 views
Uploaded on

Haskell语言的概览性介绍,内容有: ...

Haskell语言的概览性介绍,内容有:
若干语言特性(是什么让Haskell如此独特?):Lambda,Curry,
Algebraic Data Type,Type Class,
Purity,Lazy Evaluation;
对并行与并发的支持;
若干有启发性的例子以及性能问题;
Haskell在工业界的应用;

More in: Education , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • this is what i need
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
2,850
On Slideshare
2,848
From Embeds
2
Number of Embeds
2

Actions

Shares
Downloads
59
Comments
1
Likes
5

Embeds 2

https://twitter.com 1
http://pmomale-ld1 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Hi Haskell
  • 2.
    • “ A language that doesn’t effect how you think about programming is not worth learning”
    Alan Perlis
  • 3. 提纲
    • 概述
    • 若干语言特性(是什么让 Haskell 如此独特?)
      • Lambda , Curry
      • Algebraic Data Type , Type Class
      • Purity, Lazy Evaluation
    • 也许来个中场休息? (optional)
    • 对并行与并发的支持
    • 若干例子以及性能问题
    • Haskell 在工业界的应用
    • 总结
  • 4. 编程范式 (Programming Paradigm)
    • 令一门编程语言区别于其它语言的根本在于它所提供的编程范式
    • 编程范式指的是编程活动中所遵循的根本风格。它包括选取何种基本元素来构成程序(比如对象,函数,变量,约束条件等等)以及用何种方式来表达计算过程(比如赋值、表达式求值,数据流等等)。 -- 维基百科
  • 5. 你知道并用过多少种编程范式?
    • Imperative
    • Declarative
    • Object-Oriented
    • Aspect-Oriented
    • Event-Driven
    • Functional
    • Generic
    • Logic
    • Concurrent
  • 6. 其实还有更多!
  • 7. Functional Programming
    • 在 FP 这种编程范式里,计算是通过对函数的求值 (evaluation) 来组织的,它尽量避免涉及状态与可变 (mutable) 数据。 FP 强调的是函数的施用 (application) ,与之相对的命令式编程强调的则是状态的改变。
    • 几乎所有的主流语言都是偏向命令式的。
  • 8.
    • 简单来说 ,Haskell 是一门通用的、静态强类型的、
    • pure (该叫纯粹还是纯洁呢? ) 的、函数式编程语言。
    • 它提供的最基本的编程范式是 FP ,另外还能支持其它多种范式。
  • 9. Lambda 表达式(匿名函数)
    • (x y->x*10+y) 5 9
    • --59
    • 大部分时候可以象动态语
    • 言那样不写类型声明,编
    • 译器会尽全力推导出表达
    • 式的类型,如果推导失败,
    • 它会抱怨的
    • //JavaScript
    • (function (x,y){
    • return x*10 + y
    • })(5,9)
  • 10. First-Class Function & High Order Function
    • 函数是语言中的一等公民,意味着它享有和 Int 、 Float 这些基本类型一样的公民权利:
      • 函数本身可以作为参数传递
      • 函数本身可以作为返回值
      • 函数本身可以作为复合类型数据的一部分
    • 高阶函数是这样一个东东:
      • 或者它的参数是另外的函数
      • 或者它的返回值是一个函数
  • 11. Currying(Partial Application)&High Order
    • -- f::Int->Int->Int
    • -- f::Int->(Int->Int)
    • f x y=x*10 + y
    • f5 = f 5
    • f7 = f 7
    • f5 9 -- 59
    • f5 1 -- 51
    • f7 9 -- 79
    • f7 1 -- 71
    • //JavaScript
    • function f(x) {
    • return function(y) {
    • return x * 10 + y
    • }
    • }
    • f5 = f(5)
    • f7 = f(7)
    • f5(9) // 59
    • f7(1) // 71
  • 12. 高阶函数的应用 - 函数式 3D 建模
    • 参数化曲面 (R,R) -> (R,R,R)
    • 隐式曲面和空间区域: (R,R,R) -> R, 通过计算结果的符号来判断是否在区域内
    • 高度图: (R,R) -> R
    • 2D 曲线 : R -> (R,R)
    • 变换 : (R,R,R) -> (R,R,R)
    • 图像 : (R,R) -> Color
  • 13. Example - FieldTrip http://www.haskell.org/haskellwiki/FieldTrip
    • talk is cheap
    • show me the running code
  • 14. Example - FieldTrip
    • circle :: Curve2
    • semiCircle :: Curve2
    • -- 让曲线绕着 Z 轴转一圈
    • revolve :: Curve2 -> ParamSurf
    • torus :: R -> R -> ParamSurf
    • -- sr :内径 cr: 截面半径
    • torus sr cr = revolve (const (sr,0) ^+^ const cr *^ circle)
    • sphere = revolve semiCircle
  • 15. Example - 函数式 3D 建模
    • 采用类似的思想,我们还能描述更复杂的 3D 场景
  • 16. Algebraic Data Type
    • data 是关键字,用来定义新的数据类型,可以带零或多个类型参数
    • 每个新类型有一或多个 constructor 用来创建该类型的值
    • 每个 constructor 有零或多个参数,参数的类型可以是类型参数指定的类型以及任意可见类型
    • data Maybe a =
    • Just a
    • | Nothing
    • data Tree a =
    • Empty
    • | Leaf a
    • | Node (Tree a)(Tree a)
    递归的类型定义 带一个参数的 Constructor 不带参数的 Constructor
  • 17. Algebraic Data Type
    • 用具体的参数类型来具化 Maybe : Maybe Int
      • Just 20
      • Nothing
    • 当我们拿到一个 Maybe Int 的值,如何知道它包裹的整型数到底是多少?
  • 18. Pattern Matching
    • constructor 可以作为函数来创建值
    • 也可以用在 pattern 里萃取被包裹的值
    • tree =
    • Node (Leaf 4) (Node Empty (Leaf 5))
    • accum Empty = 0
    • accum (Leaf a) = a
    • accum (Node left right) = (accum left) + (accum right)
    • accum tree -- 9
  • 19. 某种多态的函数
    • 试着定义这样一个函数,它判断某个值是否在 list 里
    • 作为懒惰的程序员,我们当然希望函数的定义只写一次
    • 问题来了,我们怎么样描述这样一种数据类型,它的值是可以进行相等性测试的?
  • 20. Type Classes
    • class Eq a where
    • (==) :: a -> a -> Bool
    • elem :: Eq a => a->[a]->Bool
    • elem k (x:xs)
    • | k == x = True
    • | otherwise = elem k xs
    • elem k [] = False
    OO 的 class
  • 21. Instance of Type Classes
    • instance Eq (Maybe a) where
    • Just v1 == Just v2 = v1 == v2
    • Nothing == Nothing = True
    • _ == _ = False
  • 22. Lazy Evaluation
    • a = [1..] -- infinite list
    • take 3 a -- [1,2,3]
  • 23. Purity
    • 好吧, Functional 我早就明白了,
    • 可“纯粹”是什么?
  • 24. Purity
    • variable 一旦和某个数据绑定了就不可再修改了,
    • 所以它不再是可变的量,而仅仅是一个不可变的值的名
    • 字。
    • a = 3
    • a = 19
  • 25. Purity
    • 函数不会有 side effect ,不会对数据做破坏性的修改,不会
    • 改变外部世界的状态,它的输出只依赖它的输入,任何时刻,
    • 给定同样的输入,一定得到同样的输出。数学中的函数从来就具
    • 有这样的性质,可在大多数编程语言中这种美好的性质却被毁了。
  • 26. Referential Transparent
    • 能用 2 * f(x) 来替换 f(x) + f(x) 吗?
    • int y = 10;
    • int f(int i)
    • {
    • return i + y++;
    • }
    • f(5) + f(5); // 15 + 16 = 31
    • 2 * f(5); // 2 * 15 = 30
  • 27. 能用来做事吗?
    • 如果连状态都不能改变,那它有个鸟用!
    • 不要误会,所谓不能改变状态指的是函数求值的时候不允许改变状态,并不意味着程序运行的时候不能改变状态
    • 这是什么意思?
  • 28. IO Action
    • IO () 是一种 IO 动作,它是普通的 first-class 的数据,如果它被执行就会做某些输入输出操作, IO 动作只能被其它的 IO 动作嵌套, main 是最外层的 IO 动作,也是程序的入口点
    • 一个 IO 动作在创建的时候并不会执行,只有在嵌套它的外层动作被执行时才会跟着执行,所以执行和函数求值是不同的
    • 所有的 IO 动作都是由运行程序开始执行 main 而引发的
    --putStrLn :: String -> IO () --main :: IO () main = putStrLn "Hi Haskell!"
  • 29. Monad
    • 所有会引发状态改变的动作(包括 IO Action )都是一种 Monad 。
    • 听起来象是 Monster !
    • Haskell 最大的错误是把 Monad 叫作 Monad !或许应该喊它 "warm fuzzy thing" ( 暖毛毛 )!
      • -- Simon Peyton Jones , Haskell 设计者之一
  • 30. Monad
    • class Monad m where
    • bind :: m a -> (a -> m b) -> m b
    • inject :: a -> m a
    Monad m a bind inject a (a -> m b)
  • 31. Example - 函数式音乐编程
    • 创建一种 DSL ,既能表达高层的音乐结构,也能表达底层的声音信号处理。
    • 什么特性特别有助于在 Haskell 里创建 EDSL ?
      • 纯洁的函数和高阶函数
      • Algebraic Data Type
      • 强类型检查
      • 惰性求值
      • 二元函数的中缀写法
  • 32. Example - 函数式音乐编程 , Hommage Haskell Offline Music Manipulation And Generation EDSL http://substitut-fuer-feinmotorik.net/projects/haskellommage
  • 33.
    • 并发与并行
  • 34. 线程
    • 非操作系统线程,极为轻量
    • 你可以成千上万地随便创建
    • forkIO :: IO () -> IO ThreadId
    • forkIO (writeFile "temp.txt" "haskell thread")
  • 35. Shared Mutable State Concurrency
    • Race conditions due to forgotten locks
    • Deadlocks resulting from inconsistent lock ordering
    • Corruption caused by uncaught exceptions
    • Lost wakeups induced by omitted notifications
  • 36. Software Transactional Memory(STM)
    • 一组动作可以作为一个 transaction 被执行以保证原子性,一旦线程进入这个原子块,那么其它的线程在该原子块退出之前无法看到其做的修改,同样,这个线程在此期间也无法看到别人做的修改
    • 在退出原子块的时候,结果要么是 a 要么是 b
      • transaction 成功执行,其它线程可以立刻看见它所做的状态修改
      • transaction 执行失败,所有的修改被抛弃
  • 37. STM Sample
    • import Control.Concurrent.STM
    • type Bal = TVar Float
    • transfer::Float->Bal->Bal->STM ()
    • transfer qty fromBal toBal = do
    • fromQty <- readTVar fromBal
    • toQty <- readTVar toBal
    • writeTVar fromBal (fromQty - qty)
    • writeTVar toBal (toQty + qty)
  • 38. 事务执行
    • transferTest = do
    • alice <- newTVar 12
    • bob <- newTVar 4
    • transfer 3 alice bob
    • -- atomically:: STM a -> IO a
    • main = atomically transferTest
  • 39. Composable STM
    • orElse :: STM a -> STM a -> STM a
    • retry :: STM a
    • throwSTM :: exception -> STM a
    • catchSTM :: STM a -> (exception->STM a) -> STM a
    • instance Monad STM
    • complexAction = action1 `orElse` action2
    • main = atomically complexAction
  • 40. 让我们并行地工作吧!
    • -- 一个顺序程序
    • sort :: (Ord a) => [a] -> [a]
    • sort (x:xs) = lesser ++ x:greater
    • where lesser = sort [y | y <- xs, y < x]
    • greater = sort [y | y <- xs, y >= x]
    • sort _ = []
  • 41. 让我们并行地工作吧!
    • -- 一个并行程序
    • import Control.Parallel (par, pseq)
    • parSort :: (Ord a) => [a] -> [a]
    • parSort (x:xs) = force greater `par`
    • ( force lesser `pseq` (lesser ++ x:greater))
    • where lesser = parSort [y | y <- xs, y < x]
    • greater = parSort [y | y <- xs, y >= x]
    • parSort _ = []
  • 42. 并行 FP 并不遥远
    • Map-(Filt)-Reduce(Haskell 里叫 Fold) ,是 FP 里司空见惯的 pattern
    • Mapper 、 Filter 和 Reducer 在处理某个数据集合时并不依赖于其它的数据集合,天生就适合并行化
  • 43. 并行 FP 并不遥远
    • 所以, Google 将此 pattern 发扬光大,用于大规模并行化数据处理,打造了经典的 Map/Reduce 编程框架(尽管采用了 C++ 来实现),和 Google File System 、 BigTable 一道成为 Google 搜索技术的三大基石
    • Hadoop, Map/Reduce 的开源实现,为无数互联网公司所使用
    • 其实我们每天都在享受着 FP 提供的服务
  • 44. 用 Haskell 做一个简单的 MapReduce 框架
    • import Control.Parallel.Strategies
    • mapReduce ::
    • Strategy b -- evaluation strategy for mapping
    • -> (a -> b) -- map function
    • -> Strategy c -- evaluation strategy for reduction
    • -> ([b] -> c) -- reduce function
    • -> [a] -- list to map over
    • -> c
    • mapReduce mapStrat mapFunc reduceStrat reduceFunc input
    • = mapResult `pseq` reduceResult
    • where mapResult = parMap mapStrat mapFunc input
    • reduceResult = reduceFunc mapResult `using` reduceStrat
  • 45. 异构并行计算
    • 绝大多数的个人电脑中都有一个强劲的并行处理器:显卡中的 GPU !
    • 没有道理限制代码只能在 CPU 上奔跑
    • 对 GPU 编程: Shader 、 CUDA 、 OpenCL
    • GPU 的执行模型天生就适合 FP
    • GPipe ,一种 EDSL ,也是一种函数式的 GPU 编程模型 , 直接用 Haskell 写 GPU 程序,从而利用 Haskell 的种种迷人特性,运行时动态生成 OpenGL 的 GLSL ,提交给显卡执行
  • 46. Example - 函数式 GPU 编程
    • GPipe
    • http://www.haskell.org/haskellwiki/GPipe
  • 47. Parser Combinator
    • 每个程序员或多或少都会干点 parse 的工作
    • 所谓 parse ,其实就是将一段无结构的数据(通常是线性的字符串、二进制流)转换成定义良好的结构化数据
    • 有许多工具 ( 比如 Lex 、 Yacc 、 Flex 、 Bison 、 Antlr) 自动生成 parse 代码
    • Haskell 社区首先探索了一种独特的方式来构建复杂的 parser ,称为 Parser Combinator 。这种思想纷纷为许多其它语言所借鉴。
  • 48. Example - Parser Combinator for JavaScript
    • parser 是这样一个函数 :String -> Result
    • Result 是一个对象,包含 3 个字段:
      • remaining: 剩下的有待 parse 的字符串
      • matched: 被该 parser 成功 parse 的字符串
      • ast: parse 后生成的抽象语法树
    • 有若干预定义的基本的 parser ,比如
      • range(&quot;0&quot;, &quot;9&quot;)
      • token(&quot;begin&quot;)
    • parser 可以用 combinator 组合起来,得到一个新的 ( 更复杂的 )parser
      • repeat1(alternate(sequence(parser1, parser2), parser3))
  • 49. 这些 EDSL 的共同点
    • 把你对特定问题的“描述”送进头等舱,成为 first-class 的
    • 结构化数据,为其选择合适的 combinator ,使之不断组合产生
    • 更复杂的方案,直到能完全描述出最终的程序意图。
  • 50. 性能
    • 天下武功,唯快不破 -- 火云邪神
    • The Computer Language Benchmarks Game  
      • http://shootout.alioth.debian.org/
      • 平均来说, Haskell 的速度是 C 的 1/5
    • 眼见为实 —— 2D 水波特效
      • http://blog.csdn.net/soloist/archive/2009/04/09/4060081.aspx
  • 51. 真有人用它来做产品吗?
  • 52. 都有谁呢?
  • 53. 本次分享的起因
    • 前台技术中心要成立兴趣小组学习一门新语言,在比较过多门语言后,选择了 Haskell
    • FP 正在深刻地影响工业界。比如 Scala ,它的目的是将 Haskell 的思考方式带给 Java 程序员,已经成为 JVM 上的主流语言,正在成为其上的统治性语言
    • 无论你常用的是什么语言,掌握一门 FP 尤其是 Haskell 这样的纯粹的 FP ,都会使你成为更好更好的 programmer
  • 54. 关于我
    • 邓际锋
    • [email_address]
    • http://blog.csdn.net/soloist
    • 个人研究兴趣包括
    • 编程语言的设计与实现
    • 交互式艺术及 FP 在该领域的应用
    • 如何为儿童和非技术人员开发富有乐趣的创作工具
  • 55.
    • 谢谢!