Sml 两个列表的强并
我定义了函数:Sml 两个列表的强并,sml,Sml,我定义了函数: fun concaten(x,y) = if (x = []) then y else hd(x) :: concaten(tl(x),y); 以及: fun existsin(x,L) = if (L=[]) then false else if (x = hd(L)) then true else existsin(x,tl(L)); 我现在试图定义一个类型为(((list*list)->li
fun concaten(x,y) =
if (x = [])
then y
else hd(x) :: concaten(tl(x),y);
以及:
fun existsin(x,L) =
if (L=[])
then false
else if (x = hd(L))
then true
else existsin(x,tl(L));
我现在试图定义一个类型为(((list*list)->list)->list)
的函数,它看起来很模糊,如下所示:
fun strongunion(x,y) =
val xy = concaten(x,y);
if xy=[]
then []
if (existsin(hd(xy),tl(xy)) andalso x!= [])
then strongunion(tl(x),y)
else if (existsin(hd(xy),tl(xy)) andalso x = [])
then strongunion(x,tl(y))
else if (x != [])
then hd(xy) :: strongunion(tl(x),y)
else hd(xy) :: strongunion(x,tl(y));
它采用两个列表的“强”并集,即它处理错误输入(元素重复的列表)。当然,这段代码在语法上是无效的,但我之所以包含这段代码,是为了说明这样一个函数在命令式语言中是什么样子的
我开始这样做的方式是首先连接列表,然后从该连接中删除重复的元素(从技术上讲,我将向空列表添加非重复的元素,但这两个操作是等价的)。要做到这一点,我想我应该设计一个函数来获取两个列表(type list*list),将它们转换为它们的串联(type list),然后执行重复删除(type list),类型为(((list*list)->list)->list)
我的问题是,我不知道如何在SML中做到这一点。我被要求对一个我是助教的类使用SML,否则我就不会麻烦它,而是使用Haskell之类的东西。如果有人能告诉我如何构造这样的高阶函数,我应该能够处理其余的,但我在阅读SML文献时没有遇到这样的构造。我有点不确定强并集是否意味着除并集以外的任何东西。如果假定函数并集:“”列表*“”列表->“”列表
将两个不重复的元素列表作为输入,则可以通过有条件地将一个列表中的每个元素插入另一个列表,使其生成不重复的并集:
(* insert a single element into a list *)
fun insert (x, []) = [x]
| insert (x, xs as (y::ys)) =
if x = y
then xs
else y::insert(x, ys)
(* using manual recursion *)
fun union ([], ys) = ys
| union (x::xs, ys) = union (xs, insert (x, ys))
(* using higher-order list-combinator *)
fun union (xs, ys) = foldl insert ys xs
试一试:
- val demo = union ([1,2,3,4], [3,4,5,6]);
> val demo = [3, 4, 5, 6, 1, 2] : int list
但是,请注意,
union
不是高阶函数,因为它不将函数作为输入或返回函数。您可以使用一个稍微拉伸的定义,并将其变为curry,即,联合:“一个列表->”一个列表->“一个列表->”一个列表
,并且在仅将其部分应用于一个列表时,可以说它的顺序更高,例如,像联合[1,2,3]
。它甚至不会是完全多态的,因为它只接受可以比较的类型列表(例如,您不能接受两组函数的并集)。在Haskell中,除了标点符号上的细微差异外,它几乎是相同的;除此之外,该版本不假设其输入没有重复项,并以O(n²)运行以删除任何重复项。Haskell对于SML/NJ所具有的有效集具有。