函数程序设计 Functional Programming sist.sysu/~qiaohy/FP2012
Post on 02-Jan-2016
152 Views
Preview:
DESCRIPTION
Transcript
函数程序设计Functional Programming
http://sist.sysu.edu.cn/~qiaohy/FP2012/
乔 海燕qiaohy@mail.sysu.edu.cn
020-31981361
Important links
• All about the course: http://sist.sysu.edu.cn/~qiaohy/FP2012
• All about Haskell: http://haskell.org
课程安排与要求• 每周四 13 ~ 15 节, 2~13 周;• 地点:实验室 B403
• 讲义: Haskell 函数程序设计;• 成绩评定:平时成绩 50% + 期末成绩 50% ,平时成绩包括– 课堂参与;– 课堂、课下作业;
函数程序设计简介
• 函数程序设计语言的历史背景• 什么是函数程序设计• 函数程序设计的特点• 函数与类型• Hugs – 一个 Haskell 解释器
简介
• 历史背景• 什么是函数程序设计• 函数程序设计的特色• 函数与类型• Hugs – 一个 Haskell 解释器
软件危机
• 如何应对计算机程序日益增加的规模和复杂性 (LOC, line of code. Window 3.1(1992) 3million LOC, Windows 2000 30-50million LOC).
• 如何降低开发软件和维护软件的费用 ( maintenance can be up to 70%, including understanding, debugging and modifying the code)
• 如何增强我们对于软件正确性的信心 (The European Ariane 5(1996), cost 10 years and $7billion, explode after 40s in its maiden voyage; the floating point division in the Pentium processor cost Intel around 470 million )
程序设计语言一种解决办法是设计一种全新的语言 :
• 编写的程序结构、内容简洁,语义清晰,具有很高的抽象性;
• 支持软件的重用;• 支持快速原型设计;• 提供解决问题的工具;• 支持和鼓励形式化验证。函数程序设计语言较好地到达了上述目标。
历史背景 1920s–1940s:
and
Alonzo Church Haskell Curry
developed lambda calculus ( λ 演算) , 它是一个函数的理论,也是串行计算的一个模型。
历史背景 1960s:
John McCarthy
develops the first functional language Lisp, influenced by lambda calculus, but still with variable assignments.
历史背景• Late 1960s: Peter Landin develops ISWIM, th
e first pure functional language, based strongly on lambda calculus
• 1978 John Backus publishes FP, a functional language that emphasized high-order functions and calculating with programs.
• Mid1970s: Robin Milner develops ML, the first of the modern functional languages, which introduced type inference and polymorphic types.
历史背景• David Turner develops Miranda
• 1988: A committee of prominent researchers publishes the first definition of Haskell, a standard lazy functional language.
• 1999: The committee publishes the definition of Haskell98
Introduction
• 历史背景• 什么是函数程序设计• 函数程序设计的特点• 函数与类型• Hugs – 一个 Haskell 解释器
什么是函数程序设计 ?• C, Java, Ada and Pascal 是命令式( imperative
)语言 : 一个程序时一些命令的序列,程序运行时命令按顺序执行。关注的焦点 : 如何 进行计算 .
• 一个函数程序定义了如何将输入数据转换为输出数据,它是一个表达式:程序的运行通过计算表达式实现。关注焦点 : 计算什么 .
• 函数程序设计基于一种不同于其他程序设计语言的程序观:一个程序是从输入到输出的函数,程序的执行是表达式的计算,而非命令的执行。Let the machine do machine’s work and
let the human do human’s work.
什么是函数程序设计 (2)• 表达式由函数和基本值构成 . • 例 : 计算从 1至 10 的和 .
命令式语言 : total = 0; for (I = 1; I<=10, I++) total += I;
Haskell 语言 : sum [1..10]
sum 是一个函数 , [1..10] 表示 1 至 10 的整数 .
简介
• 背景• 什么是函数程序设计• 函数程序的特点• 函数与类型• Hugs – 一个 Haskell 解释器
函数程序设计的特点• 简洁、优美 . 函数程序更简洁。例如 : qsort.
• 容易理解 qsort [] = [] qsort (x:xs) = qsort less ++ [x] ++ qsort more where less = [y | y <- xs, y < x] more = [y | y <- xs, y >= x]
函数程序设计的特点 (2)• 无副作用,较少的错误 . The result of a functio
n (no side effect) is determined by its input, and only by its input. The result doesn’t depend on the evaluation order. This eliminates a whole class of bugs in imperative languages.
• 强类型. It is impossible to apply a function to a bool
ean when you should apply it to an int. Bugs are caught at compile-time, rather than run-time. This also makes it less buggy.
Features of functional programming(3)
• 代码重用 : Polymorphism enhance reusability. For example, qsort can be used to lists of int, lists of double, lists of any type that has < and >= defined.
• 模块化 : A good programming language support modular programming, and this requires good glue. Functional programming provides two kinds of glue- higher order functions and lazy evaluation.
Features of functional programming(4)
• 高阶函数 A higher order function can takes functions as arguments and return a function.
• 惰性计算 Non-strict functional languages have another powerful feature: they only evaluate as much of the program as is required to get the answer - this is called lazy evaluation (惰性计算) .
• See “Why functional programming matter?”
简介
• 背景• 什么是函数程序设计• 函数程序设计的特点• 函数和类型• Hugs – 一个 Haskell 解释器
值与表达式一个值是一个数据 :
2, 3.1415, “Alice”, …
一个表达式可以计算其值 :
2+3, pi*r^2, -b + sqrt(b^2 – 4*a*c)/(2*a), …
表达式 : 由值、运算符和函数构成 ;
一个值是不可再计算其值的表达式 .
operation function
定义和类型• 一个类型是同类型值的集合,或者说,这些值支持一组相同的运算。例如,整数的集合 Int ,布尔值的集合 Bool ,图形的集合。
• 2 :: Int 读作“ 2 具有类型 Int” , 称之为类型说明 .
• 一个定义给一个特定类型的表达式赋予一个名
area :: Int
area = 3 * 4名称以小写字母
开始
说明值的类型
说明如何计算表达式的值
函数与类型• 一个函数具有一些输入 (arguments, paramet
ers) 并返回一个输出值 (result).
• 设 A 是函数 f 的输入值集合,称之为 f 的定义域( the domain of the function f ) .
• 设 B 是函数 f 的结果值的集合,称之为 f 的值域( the codomain of the function f.)
• 称 f 是从集合 A 到集合 B 的函数。• 用 A -> B 表示 A 到 B 的所有函数的集合 。 A -> B 成为函数 f 的类型。
函数定义一个函数定义说明如何由输入计算输出。
double :: Int -> Int
double x = 2 * x
area :: Int -> Int -> Int
area l b = l * b
参数
说明输入类型和输出类型
函数体说明如何由输入计算结果
函数名
函数应用• 在数学上,函数应用通常表示为函数名后接包含在括号内的参数,如 f(x, y), f (2, 4). 在 Haskell 中 , 函数应用表示为函数名后接依次用空格分隔的参数,如, f x y, f 2 4.
• 在 Haskell 中 , 括号用于组织表达式 , 如 f 2 (2 + 2)
• 函数应用比其他运算符具有更高的优先级,如 f 2 + 4 等价于 (f 2) + 4
函数程序
• 一个函数程序由一些函数和值构成。• 一个函数通常是用其他函数定义的。• 一个主函数计算整个程序在输入下的输出。
Your first Haskell program 使用一个文本编辑器编辑如下文本并存储为
FirstScript.hs:{- My first Haskell script
FirstScript.hs
-}
-- size is define as an integer
size :: Int
size = 23 + 45
square :: Int -> Int
square n = n * n
double :: Int -> Int
double x = 2 * x
example :: Int
example = double (size – square (3 – 23))
注释• -- 单行注释• {- 多行注释 …
-}
脚本格式 LayoutHaskell 也使用 {,} 和 ; 组织定义 . 但是,更多的是使用版面格式规则。
基本规则 : 如果新的一行开始于前一行的右边,则新行是前一行说明(定义)的继续,否则是另一个说明(定义)的开始。
例如, f x y = x + y +123g x = f x x
简单规则 : 一系列的同层定义应该始于同一列。
Layout rule
OK Not OK
max :: Int -> Int -> Int max x y = if x>=y
then x else y min :: Int -> Int -> Int min x y = …
max :: Int -> Int -> Intmax x y = if x>=y then min :: Int -> Int -> Int min x y = …
Haskell 中的命名• 函数名和变量名以小写字母开始。• 类型名和构造符名以大写字母开始。如 Int,
True.
• 保留字( Reserved words ) : case class data default deriving do else if import in infix infixl infixr instance let module newtype of then type where
简介
• 背景• 什么是函数程序设计• 函数程序设计的特点• 函数与类型• Hugs – Haskell 解释器
运行 Hugs• Hugs 是 Haskell 的一个实现,它的 PC版本 和 Unix 版本均可在下列网站免费下载安装 www.haskell.org/hugs/
• 开始运行 Hugs, 执行 hugs FirstScript.hs
Main > ( 在这里你可以运行你的程序 )
例如 ,
Main > double 23 – square (double 4)
- 18
Hugs 命令• :load first.hs 载入 Haskell 脚本 first.hs
• :reload 重新载入最近载入的文件• :type e 显示 e 的类型 • :edit first.hs 编辑文件 first.hs
• :? 列出 Hugs 命令• :quit 退出系统 Hugs 命令还可以缩写为命令的第一个字母 ,如 :l 等价于 :load.
错误信息( Error messages )• 语法错误( Syntax error ) :
Prelude> 2-(3-4))
ERROR: Syntax error in expression
• 程序错误( Porgram errors ) :
Prelude> 4 `div` (double 2 – 4)
Program error: [primDiviInt 4 0]
类型错误 Type ErrorType error:
main> double square
ERROR: Type error in application
*** expression : double square
*** term : square
*** type : Int -> Int
*** does not match : Int
标准引导库
运行 hugs 时,我们会看到 Reading file: “C::\HUGS\lib\Prelude.hs”
标准引导库 Prelude.hs 包含一些常用的算术函数和列表函数。
Haskell还提供一些其他标准函数库。
模块( Modules )• 一个计算机软件由成千上万行定义(说明,命令,语句)构成。为了开发和维护大规模的软件,我们必须将一个软件系统分解成为相对独立的、较小的程序,称之为模块。
• 一个模块可以调用其他模块。• 一个模块可以控制此模块输出那些定义。• 一个 Haskell 程序由一些模块构成,其中一个称为 Main ,并输出一个值 main.
模块 (2)一个模块包含一系列 Haskell 定义 .
module Bee where
import Ant
…
模块名
调用其他模块
模块体
作业 :
1. 下载安装 hugs
2. 编辑 FirstScript.hs, 并调入 hugs 运行3. 找到 Prelude.hs, 试着运行一些函数4. 在 FirstScript.hs 中加入更多的函数
top related