SML:比较两个列表的每个元素而不存储状态信息吗?

时间:2019-03-04 03:53:00

标签: list sml smlnj

我有一个SML分配,通常的想法是我不应该存储状态信息,不应该使用内置的库函数等,而只能以功能方式解决。不确定如何做:

这个问题需要将两个列表的每个元素一起比较:

输入

list1:[(3,3,5),(5,4,7),(2,3,4)]; list2:[3,6];

输出

newList:[(3,3,5),(2,3,5)]

本质上,当list1的元组arg中的第二个元素与list 2中的项匹配时,我应该将list1项添加到新的输出列表中。

我实现它的方式:

fun thing(x, y) = 
   if null x then []
   else if #2 (hd x) = (hd y) then hd x @ thing(tl x, y)
   else thing(tl x, y);

显然,这样做的问题是我丢失了状态信息:如何将list1中的每个元素与list2中的每个元素进行匹配?

1 个答案:

答案 0 :(得分:1)

  

当list1的元组arg中的第二个元素与列表2中的项目匹配时,
  那么我应该将list1项目添加到新的输出列表中。

fun thing(x, y) = 
  if null x then []
  else if #2 (hd x) = (hd y) then hd x @ thing(tl x, y)
  else thing(tl x, y);

使用模式匹配代替if null x then ...hd xtl x

fun thing ([], _) = ...
  | thing ((x,y,z)::haystack, needles) = ...

要确定y是否是needles的成员,请建立成员资格函数:

fun elem (p, []) = false
  | elem (p, q::qs) = p = q orelse elem (p, qs)

检查是否elem (y, needles)以确定是否将(x,y,z)作为结果的一部分。

thing递归应用于haystackneedles

使用::(cons)运算符而不是@(追加)来构成递归结果。


以下是使用库函数解决此练习的方法:

fun curry f x y = f (x, y)
fun thing (haystack, needles) =
    List.filter (fn (x,y,z) =>
      List.exists (curry op= y) needles) haystack