【问题标题】:Strong union of two lists两个列表的强联合
【发布时间】:2017-11-28 16:30:55
【问题描述】:

我已经定义了函数:

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));

它采用两个列表的“强”联合,即它与错误输入(具有重复元素的列表)作斗争。当然,这段代码在语法上是无效的,但我包含它的原因是为了展示这样一个函数在命令式语言中的样子。

我开始这样做的方法是首先连接列表,然后从该连接中删除重复的元素(嗯,从技术上讲,我将非重复元素添加到空列表中,但这两个操作因此是等效的)。为此,我想我会设计一个函数来获取两个列表(类型 list*list),将它们转换为它们的串联(类型列表),然后执行重复删除(类型列表),其类型为 (((list*list) -> list) -> list) .

我的问题是我不知道如何在 SML 中执行此操作。对于我是 TA 的课程,我需要使用 SML,否则我不会打扰它,而是使用 Haskell 之类的东西。如果有人能告诉我如何构造这样的高阶函数,我应该能够处理其余的事情,但我在阅读 SML 文献时还没有遇到过这样的构造。

【问题讨论】:

  • 它在 Haskell 中几乎相同,除了标点符号略有不同。
  • 在 Haskell 中它可能看起来像 Data.List.union;除了该版本不假定其输入没有重复项并在 O(n²) 中运行以删除任何重复项。 Haskell 有 Data.Set 用于高效集合,而 SML/NJ 有 RedBlackSetFn

标签: sml


【解决方案1】:

我有点不确定strong union是否意味着union。如果您假设函数union : ''a list * ''a list -> ''a list 将两个没有重复的元素列表作为输入,那么您可以通过有条件地将一个列表中的每个元素插入另一个列表来使其生成没有重复的联合:

(* 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 不是高阶函数,因为它不将函数作为输入或返回函数。您可以使用稍微拉伸的定义并使其柯里化,即union : ''a list -> ''a list -> ''a list,并说在仅将其部分应用于一个列表时它是高阶的,例如喜欢union [1,2,3]。它甚至不是完全多态的,因为它只接受可以比较的类型列表(例如,你不能将两组函数合并)。

【讨论】:

    猜你喜欢
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2019-09-11
    相关资源
    最近更新 更多