任务一
函数map和filter定义如下:
(* map: ('a -> 'b) -> 'a list -> 'b list *)
fun map f [ ] = [ ]
| map f (x::xs) = (f x) :: (map f xs)
(* filter: ('a -> bool) -> 'a list -> 'a list *)
fun filter f [] = []
| filter f (x::xs) = if f x then x :: (filter f xs)
else filter f xs
推导下列表达式的类型和计算结果,并描述其功能。
map (filter (fn a => size a = 4)) [[“Sunday”, “Monday”], [“one”, “two”, “three”, “four”, “five”], [“year”, “month”, “day”]]
分析:map是批处理函数,对列表中所有数据用filter函数进行处理
filter的功能是借助f函数处理列表,用一个列表生成一个新列表
在这里是筛选出列表中长度为4的字符串取出生成新的列表
表达式的类型:
( (string->bool)-> string list -> string list ) ->sring list list -> string list list
计算结果
[ [] , [“four”,”five”] , [“year”] ]
任务二
编写函数thenAddOne,要求
- 函数类型为: ((int ->int) * int) -> int
- 功能为将一个整数通过函数变换(如翻倍、求平方或求阶乘)后再加1
fun thenAddOne (f:int->int ,x:int) = f x +1;
注:这里没有进行实例函数验证,需要自行补充,任务三同。
任务三
编写函数mapList,要求
- 函数类型为: ((‘a -> ‘b) * ‘a list) -> ‘b list
- 功能为实现整数集的数学变换(如翻倍、求平方或求阶乘)
fun mapList (f,[ ]) =[ ]
| mapList (f,(x::L))=(f x) :: (mapList (f,L));
任务四
编写函数mapList’,要求
- 函数类型为: (‘a -> ‘b) -> (‘a list -> ‘b list)
- 功能为实现整数集的数学变换(如翻倍、求平方或求阶乘)
- 比较函数mapList’和mapList,分析、体会它们有什么不同。
fun mapList' f = fn L =>
case L of
[ ] => [ ]
| x::R => (f x) :: (mapList' f R);
不同请自行观察mapList和mapList‘的类型
任务五
编写函数
-
exists: (‘a -> bool) -> ‘a list -> bool
-
forall: (‘a -> bool) -> ‘a list -> bool
对函数p: t -> bool, 整数集L: t list,
有: exist p L =>* true if there is an x in L such that p x=true;
exits p L =>* false otherwise.
forall p L =>* true if p x = true for every item x in L;
forall p L =>* false otherwise.
fun exist f [] = false
| exist f (x::L) = f x orelse (exist f L);
fun forall f [] = false
| forall f (x::L) = f x andalso (forall f L);
这两个函数都“柯里化”了
任务六
编写函数
treeFilter: (‘a -> bool) -> ‘a tree -> ‘a option tree
将树中满足条件P( ‘a -> bool )的节点封装成option类型保留,否则替换成NONE
就是遍历一遍树,p x 为true 变成option类型,p x 为false 则换成NONE。
类似于批处理函数map
datatype 'a tree = Empty| Node of 'a tree*'a*'a tree;
datatype 'a options = NONE | SOME of 'a;
fun treeFilter f Empty = Empty
| treeFilter f (Node(L,x,R)) = if f x then Node(treeFilter f L,SOME x,treeFilter f R)
else Node(treeFilter f L,NONE,treeFilter f R);