250 likes | 421 Views
用 ML 编写正确的程序 ML – Programming Correctly. 汪 旻 5110379036 yinger650@gmail.com. 函数 式程序设计. 过程式语言面向命令,函数式语言面向表达式 函数式语言避免繁琐的内存管理 函数式语言 要求写出可靠正确的程序 函数式语言的几个概念 函数,递归,模式匹配,多态类型检测,高阶函数,无穷数据结构,惰性求值. ML 与纯函数式编程语言的 区别. ML 是非纯函数式语言 热情 求值 没有无穷数据结构 模块 ……. 多态类型检测 异常处理 简单的 IO 指令 ……. ML 的诞生.
E N D
用ML编写正确的程序ML – Programming Correctly 汪旻 5110379036 yinger650@gmail.com
函数式程序设计 • 过程式语言面向命令,函数式语言面向表达式 • 函数式语言避免繁琐的内存管理 • 函数式语言要求写出可靠正确的程序 • 函数式语言的几个概念 • 函数,递归,模式匹配,多态类型检测,高阶函数,无穷数据结构,惰性求值
ML与纯函数式编程语言的区别 • ML是非纯函数式语言 热情求值 没有无穷数据结构 模块 …… • 多态类型检测 • 异常处理 • 简单的IO指令 • ……
ML的诞生 • ML(Meta-Language) 是一个通用的函数式编程语言,它是由爱丁堡大学的Robin Milner在二十世纪七十年代晚期开发的,现在流行的方言有Standard ML和Caml. • 启发语言:ISWIM • 影响语言:Miranda, Haskell, Cyclone, C++, F#, Clojure, Felix, Opa, Erlang …… • 设计初衷:LCF定理证明机中寻找证明策略 • ML大多被用于语言设计和操作(编译器、分析器、定理证明机), 但是它作为通用语言也被用于生化,金融系统,和宗谱数据库,一个P2P的客户/服务器程序等等。
Level 0 • Hello world “Hello world!”; (*make a string*) print it; (*output it*) • 阶乘函数 fun fac 0=1| fac n = n * fac (n -1); Level Up! LV.1 ML Programmer LV.0 ML Programmer 猿
Level 1 • 值的声明 • 命名常量 • val pi = 3.14159; • 声明函数 • fun circle_area (r) = pi*r*r; • 标识符 • 字母开头,允许数字、下划线、撇号’ • !%&$#+_*/:<=>?@\~`^|
Level 1 • 基本类型 • 数 • int, real • + - * div mod • ~ 负号 • 类型约束 • 字符串 • 连接符^ • #”0”和“0” • 真值 • orelse, andalso, not • if E then E1 else E2 - fun square x = x*x; ↓ - fun square x = x*x :real;
Level 1 • 序偶、元组、记录 • 序偶 • 向量(2.5 , ~1.2) : real*real • type vec = real * real; • 记录 • val ZS = {name=“Zhang San”, age=20, major=“CS”}; • #age ZS; > 20 : int Level Up! LV.1 ML Programmer LV.2 ML Programmer 猿
Level 2 • 表达式 • 中缀操作符(infix operator)及其优先级、结合方式 • 传值调用(add….) • 局部声明 • let ... in ... end • local ... in ... end • 支持嵌套
(* Example for infix operator *) • infix xor; • fun (p xor q) = (p orelse q) andalso not (p andalso q); • (* 中缀优先级 *) • infix 7 times; • (* 传值调用 *) • sqr(sqr(sqr(2))) • =sqr(sqr(2*2)) • =sqr(sqr(4)) • =sqr(4*4) • =sqr(16) • =16*16 • =256 • . • zero(sqr(sqr(sqr(2))) • =zero(sqr(sqr(2*2))) • =zero(sqr(sqr(4))) • =zero(sqr(4*4)) • =zero(sqr(16)) • =zero(16*16) • =zero(256) • =0
(* Example for let ... in ... end *) fun fraction (n,d) = let val com = gcd(n,d) in (n div com, d div com) end; > val fraction = fn: int * int -> int * int (* Example for local ... in ... end *) local fun itfib (n, prev, curr) : int = if n=1 then curr else itfib (n-1, curr, prev+curr) in fun fib (n) = itfib(n, 0, 1) end; > val fib = fn ; int -> int Level Up! LV.2 ML Programmer LV.3 ML Programmer 猿
Level 3 • 模块系统 • 结构 • 通过Conplex.zero这样的形式来访问 • 不同结构里的标识符可以相同 • 签名
structure Complex : ARITH = struct type t = real*real; val zero = (0.0, 0.0); fun sum ((x,y), (x',y')) = (x+x', y+y') : t; fun diff ((x,y), (x',y')) = (x-x', y-y') : t; fun prod ((x,y), (x',y')) = (x*x' - y*y', x*y' + x'*y) : t; fun recip (x,y) = let val t:real = x*x + y*y in (x/t, ~y/t) end fun quo (z,z') = prod(z, recip z'); end; signature ARITH = sig type t val zero : t val sum : t * t -> t val diff : t * t -> t val prod : t * t -> t val quo : t * t -> t end; Level Up! LV.3 ML Programmer LV.4 ML Programmer 猿
Level 4 • 多态类型检测 • 多态类型的声明 • 关于算法(Damas(1985)的博士论文) • - fun pairself x = (x,x); • > valpairself = fn : ‘a -> ‘a * ‘a • fun fst (x,y) = x; • > valfst = fn : ‘a * ‘b -> ‘a • fun snd (x,y) = y; • > valsnd = fn : ‘a * ‘b -> ‘b Level Up! LV.4 ML Programmer LV.5 ML Programmer 猿
Level 5 • List • 顺序 [3, 4] • 可重复 [3, 4, 3] • 元素类型任意 [(1,”one”),(2,”two”),(3,”three”)] : (int*string) list • :: 右结合中缀操作符cons 在表前加入一个元素 • _ 通配符 Level Up! LV.5 ML Programmer LV.6 ML Programmer 猿
Level 6 • 数据类型声明 datatype person = King | Peer of string*string*int | Knight of string | Peasant of string; fun title King = "His Majesty the King“ | title (Peer(deg,terr,_)) = "The " ^ deg ^ " of " ^ terr | title (Knight name) = "Sir " ^ name | title (Peasant name) = name;
Level 6 • 树 • 节点=节点+子树or叶子 datatype ‘a tree = Lf | Br of ‘a tree * ‘a tree; • size(tree) • 应用
val tree2 = Br(2, Br(1,Lf,Lf), Br(3,Lf,Lf)); val tree5 = Br(5, Br(6,Lf,Lf), Br(7,Lf,Lf)); val tree4 = Br(4, tree2, tree5); 4 2 5 1 3 6 7
(* make a tree *) datatype 'a tree = Lf | Br of 'a * 'a tree * 'a tree; structure Tree = struct fun size Lf = 0 | size (Br(v,t1,t2)) = 1 + size t1 + size t2; fun size Lf = 0 | size (Br(v,t1,t2)) = 1 + size t1 + size t2; fun depth Lf = 0 | depth (Br(v,t1,t2)) = 1 + Int.max (depth t1, depth t2); fun reflect Lf = Lf | reflect (Br(v,t1,t2)) = Br(v, reflect t2, reflect t1); .... end;
(* 二叉查找树 *) (*** Dictionaries as Binary search trees ***)signature DICTIONARY = sig type key (*type of keys*) type 'a t (*type of tables*) exception E of key (*errors in lookup, insert*) val empty: 'a t (*the empty dictionary*) val lookup: 'a t * key -> 'a val insert: 'a t * key * 'a -> 'a t val update: 'a t * key * 'a -> 'a t end; (*Structure Order can vary; Tree avoids referring to a free structure. *) structure Dict : DICTIONARY = struct type key = string; type 'a t = (key * 'a) tree; exception E of key; val empty = Lf;
fun lookup (Lf, b) = raise E b | lookup (Br ((a,x),t1,t2), b) = (case String.compare(a,b) of GREATER => lookup(t1, b) | EQUAL => x | LESS => lookup(t2, b)); fun insert (Lf, b, y) = Br((b,y), Lf, Lf) | insert (Br((a,x),t1,t2), b, y) = (case String.compare(a,b) of GREATER => Br ((a,x), insert(t1,b,y), t2) | EQUAL => raise E b | LESS => Br ((a,x), t1, insert(t2,b,y))); fun update (Lf, b, y) = Br((b,y), Lf, Lf) | update (Br((a,x),t1,t2), b, y) = (case String.compare(a,b) of GREATER => Br ((a,x), update(t1,b,y), t2) | EQUAL => Br ((a,y), t1, t2) | LESS => Br ((a,x), t1, update(t2,b,y))); end; Level Up! LV.6 ML Programmer LV.7 ML Programmer 猿
后期升级攻略 • 函数与算子 • 实现惰性求值 • 实现搜索策略 • 函数式程序正确性的证明 • 抽象类型(用于建立大型系统) • ML中的命令式程序设计 • 应用:LAMBDA演算解释器
总结 • 用ML可以很容易写出清晰、可靠的程序。值得作为函数式编程的入门语言。 • 在牺牲部分效率的情况下,提升程序的安全性是十分必要的。因为在函数式编程里,正确性第一,清晰性次之,效率排在第三位。 • ML在运行前会检查所有的类型和接口以防止出错,让程序员将更多的精力放在丰富语言上,而不是冗长又无用的调试和测试。 • ML远没有这次所展示的这么少,它的强大之处还待继续去深入地了解。
参考资料 • ML for the Working Programmer Second Edition, Lawrence C. Paulson • en.Wikipedia.org - ML (programming language) Functional programming 3. A Gentle Introduction to ML, Andrew Cumming, Computer Studies, Napier University 4. The ML Language - Typed Functional Programming with Assignments
问答 谢谢聆听