SML/NJ在列表元组列表中的搜索

SML/NJ在列表元组列表中的搜索,sml,smlnj,Sml,Smlnj,我对SML/NJ很陌生,有点迷路了。我一直在尝试实现一个函数,该函数将搜索包含一些列表的元组列表,例如: val x = [(5, 2, [9 , 8, 7]), (3, 4, [6, 5, 0]), (11, 12, [8, 3, 1])] 我希望函数在我的目标编号与元组元素3中的编号匹配后,将元组的第一个元素添加到新列表中。我已经尝试了几个实现,但到目前为止没有一个能够正常工作 type id = int* int* int list; val b:id list = [(5,2,[9,

我对SML/NJ很陌生,有点迷路了。我一直在尝试实现一个函数,该函数将搜索包含一些列表的元组列表,例如:

val x = [(5, 2, [9 , 8, 7]), (3, 4, [6, 5, 0]), (11, 12, [8, 3, 1])] 
我希望函数在我的目标编号与元组元素3中的编号匹配后,将元组的第一个元素添加到新列表中。我已经尝试了几个实现,但到目前为止没有一个能够正常工作

type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
val a: int list = nil;

fun findNum(nil) = a | findNum (x: id list) =
    let val tem = hd(x)
        val theList = #3tem
        val i = #1tem
        fun findMatch(nil) = a | findMatch(tem) =
            if (number = hd(theList)) then i::a 
            else findMatch (tl(theList))
    in findNum(tl(x))
    end;

 findNum(b);
我知道它写得很糟糕,这就是为什么它总是返回一个空列表。我觉得我需要执行“if-else”而不是let/in/end,这样它将递归调用列表中的其余元组。我的问题是,我不知道怎么做,因为如果我使用if/else,那么我就不能在函数中声明一些值。我很感激任何建议或暗示


谢谢。

您可以从函数
成员(x,xs)
开始,如果
x
是列表
xs
中的一个元素,则这是正确的:

fun member (x, xs) = List.exists (fn y => x = y) xs
基本情况是三个元组的列表为空。然后,
x
不会出现在任何(不存在的)三个元组的第三个元素中,结果列表为空。通过对列表的第一个元素是三元组
(i,j,xs)
和列表的尾部
ts
进行模式匹配,并询问
x
是否是第三个元素
xs
的成员,可以实现递归情况;如果是,则返回元组的第一部分,
i

fun find (x, []) = []
  | find (x, (i,j,xs)::ts) =
    if member (x, xs)
    then i :: find (x, ts)
    else find (x, ts)
使用高阶列表组合符
map
filter
的较短版本:

fun find (x, ts) = map #1 (filter (fn (i,j,xs) => member (x, xs)) ts)

以下是我的实现,其中有一些细微的改动:

type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;

fun findNum [] = [] 
  | findNum (x::xs)  =
        let 
           val theList :int list = #3 (x :id)
           val i : int = #1 x
           fun findMatch [] = false
             | findMatch (y::ys) = if (number = y) then true
                                   else findMatch ys
        in 
           if (findMatch theList = true) then i ::(findNum xs) 
           else (findNum xs) 
        end;
例如:

- findNum b;
val it = [5,11] : int list

您能否添加一个简单的输入和所需输出示例,例如输入
[(5,2,[9,8,7]),(3,4,[6,5,0]),(11,12,[8,3,1])]
您希望得到什么输出?我希望在第三个元素中的数字匹配后返回元组的第一个元素列表。所以在这种情况下应该是[5,11]。非常感谢。什么是“新列表”?这就是你所说的函数的结果值吗?是的,我指的是函数的结果值列表。太棒了。非常感谢。你的if-then-else可以缩短一点
如果(number=y),则为true,否则findMatch ys
等同于
number=y或lse findMatch ys
。类似地,
if(findMatch theList=true)then…
可以缩短为
if findMatch theList then…
@SimonShine,谢谢!!!,我不太确定,因为我在sml没有这样的经验,谢谢你的评论!!非常感谢您的帮助和解释。这个实现非常简短和干净。