八、高阶函数
1.数据标准化问题
min-max:对原始数据进行线性变换,是结果值映射到[-1,1]之间。
f:real->real 原始区间的最小值a和最大值b,f使得 f(a)=-1.0,f(b)=1.0
norm:real*real->(real->real) real*real得到一个函数real->real
fun norm(a,b) = fn=>(2.0*x-a-b)/(b-a)
- 函数norm的扩展使用
fun norm(-2.0,2.0) = fn x=> x/2.0
- 对二元组进行归一化处理
fun normpair(a,b)=
fn(x,y)=>(norm(a,b) x,norm(a,b) y)
fun normpair(a,b)=
fn(x,y)=>let
val f=norm(a,b)
in (f x,f y)
end
2.新的需求(高阶函数)
如何将一个函数应用于某种数据结构中的所有严肃
批处理:对每个元素执行相同的操作(调用相同的函数)
- 对pair的处理
pair:('a->'b)->'a*'a->'b*'b
fun pair f=fn(x,y)=>(f x,f y)
pair f 作为函数,接收一个元组,对这个元组进行处理
例如:pair (norm(~2.0,2.0)) (1.5,1.5)
- 对list处理
map:('a->'b)->('a list->'b list)
fun map f = fn L=>
case L of
[] => []
| x::R=>(f x)::(map f R)
map (norm(~2.0,2.0)):real list -> real list
map (norm(~2.0,2.0)) [1.0,1.5,2.0] =>* [0.5,0.75,1.0]
3.map函数应用:求解子集
fun map f [] = []
| map f(x::R)=(f x)::(map f R)
fun sublists []=[[]]
| sublists (x::R)=
let
val S=sublists R
in S@map(fn A=>x::A) S
end
fn A=>x::A是把x追加到A这个list上面
map (fn A=>x::A) S 是把x加到S这个list list中的每一个list上
4.联合求解:int list求和—real list 求最大值
- int list
sum:int list -> int
fun sum L =foldr (op +) 0 L
- real list
fun maxlist (x::R) = folder Real.max x R
Real.max:real*real -> real
fun foldr F z [] = z
| foldr F z (x::L) = foldr F (F(x,z)) L
fun foldr F z [] = z
| foldr F z (x::L) = F(x,foldr F z L)
其中z为初值
F为进行的操作
九、高阶函数应用
注意应用map、foldr,一个批处理,一个联合求解
1.map的应用、批处理
fun normalize (L:(real*real)list):(real*real)list =
let
val xs = map(fn(x,y)=>x) L
val ys = map(fn(x,y)=>y) L
val (xlo,xhi) = (minlist xs,maxlist xs)
val (ylo,yli) = (minlist ys,maxlist ys)
in map (fn(x,y)=>(norm(xlo,xhi) x,norm(ylo,yhi) y)) L
end
2.foldr的应用、联合求解
type point = real*real
type body = real*point
fun add ((x1,y1),(x2,y2)):point=(x1+x2,y1+y2)
fun mass (m,(x,y))=m
fun scale r (m,(x,y))=(r*m*x,r*m*y)
fun center (L:body list):point = let
val M = foldr (op+) 0.0 (map mass L)
in foldr add (0.0,0.0) (map (scale (1.0/M)) L)
3.字符串的相关操作
explode :string->char list
implode :char list->string
Char.toUpper :char->char
foldr (op^) "are belong to us": string list->string
fun capitalize (s:string) :string=
let val (x::L)=explode s
in implode(Char.toUpper x::L)
end ;
4.通用排序
- 数据预处理
对任意类型的数据,都能够进行比较
- 比较函数的实现
for int
fun compare(x:int,y:int):order=
if x<y then LESS else
if y<x then GREATER else EQUAL
for int*int
第一种:比较第一个数
fun leftcompare((x1,y1),(x2,y2))=
compare(x1,x2)
第二种:先比较第一个数,再比较第二个数
fun lexcompare((x1,y1),(x2,y2))=
case compare(x1,x2) of
LESS => LESS
| GREATER => GREATER
| EQUAL => compare(y1,y2)
二元组数据的通用比较函数lex
fun lex(cmp1,cmp2) ((x1,y1),(x2,y2))=
case cmp1(x1,x2) of
LESS => LESS
| GREATER => GREATER
| EQUAL => cmp2(y1,y2)
- 函数sorted
fun sorted cmp [] = true
| sorted cmp [x] = true
| sorted cmp (x::y::L) =
case cmp(x,y) of
GREATER => false
| _ => sorted cmp (y::L)
十、柯里函数
柯里化:把接受多个参数的函数变换成接受一个但一参数的函数,并且返回接受余下参数且返回结果的新函数的技术。