如何使用一个班轮 msl 遍历列表?

how to iterate over a list using one liner msl?

我有一个列表和一个元组(开始、结束、间隔)我正在尝试遍历列表和return列表中的元素从开始到结束的间隔步骤。例如:

cutt [1,2,3,4,77,8,7] (1,5,2);
val it = [2,4,8] : int list;

问题是我想编写一个仅使用一行来执行此操作的函数,这意味着没有递归函数,没有 if 条件,也没有模式匹配

我开始想我可以先将列表剪切到开始和结束之间的元素:

fun cutt list1 (start,end,interval) = List.drop(List.take(list1 ,end+1),start);

现在我想使用 foldl 或 foldr 来仅获取间隔跳跃中的元素,我的问题是如何遍历列表?

理论上,经过深思熟虑后,我们可以这样做,但它非常丑陋且效率低下,不应该这样做 .

让我们先放下你想放下的元素。您的基本配方有效,但您不能使用 end,因为这是保留字。

fun cutt list1 (start, stop, interval) = 
  List.drop(List.take(list1, stop + 1), start);

cutt [1,2,3,4,77,8,7] (1, 5, 2) 产生 [2,3,4,77,8].

现在,我们如何以一定间隔删除元素。我们不能使用显式递归,也不能使用模式匹配或条件。好吧,然后我们可以使用 List.tabulate 创建一个等于列表长度的列表,该列表具有包含列表元素和索引的元组。

fun cutt list1 (start, stop, interval) = 
  List.tabulate(
    stop - start + 1, 
    (fn i => 
       (i, List.nth(List.drop(List.take(list1, stop + 1), start), i))));

如果我们评估 cutt [1,2,3,4,77,8,7] (1, 5, 2) 现在我们得到 [(0, 2), (1, 3), (2, 4), (3, 77), (4, 8)]

现在我们可以根据索引过滤掉不需要的值。

fun cutt list1 (start, stop, interval) = 
  List.filter (fn (i, _) => i mod interval = 0) (List.tabulate(
    stop - start + 1, 
    (fn i => 
       (i, List.nth(List.drop(List.take(list1, stop + 1), start), i)))));

cutt [1,2,3,4,77,8,7] (1, 5, 2) 产生 [(0, 2), (2, 4), (4, 8)].

我们可以绘制索引。

fun cutt list1 (start, stop, interval) = 
  List.map (fn (_, x) => x) (List.filter (fn (i, _) => i mod interval = 0) (List.tabulate(
    stop - start + 1, 
    (fn i => 
       (i, List.nth(List.drop(List.take(list1, stop + 1), start), i))))));

cutt [1,2,3,4,77,8,7] (1, 5, 2) 产生 [2, 4, 8].

极其丑陋和低效。我不确定为什么有人教你这样写代码。随意通过删除换行符使其更加丑陋

fun cutt list1 (start, stop, interval) = List.map (fn (_, x) => x) (List.filter (fn (i, _) => i mod interval = 0) (List.tabulate(stop - start + 1, (fn i => (i, List.nth(List.drop(List.take(list1, stop + 1), start), i))))));