i have a list , and a tuple (start,end,interval) i am trying to iterate over the list and return the elements that are in list from start to end with interval steps . for example:
cutt [1,2,3,4,77,8,7] (1,5,2);
val it = [2,4,8] : int list;
the problem is that i want to write a function that does this using one line only which means no recursic function and no if condition also no pattern matching
i began by thinking i can cutt the list first only to elements between start and end using :
fun cutt list1 (start,end,interval) = List.drop(List.take(list1 ,end+1),start);
and now i want to use maybe foldl or foldr to only get elements in interval jumps , my problem is how to iterate over the list ?
In theory, after much soul-searching, we can do this, but it's hideously ugly and inefficient and should not be done.
Let's first off drop the elements you want dropped. Your basic recipe works, but you can't use end
as that is a reserved word.
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)
yields [2,3,4,77,8]
.
Now, how do we drop elements at an interval. We can't use explicit recursion, nor pattern matching or conditions. Well, then we can use List.tabulate
to create a list equal to our lists length that has tuples with the list elements and an index.
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))));
If we evaluate cutt [1,2,3,4,77,8,7] (1, 5, 2)
now we get [(0, 2), (1, 3), (2, 4), (3, 77), (4, 8)]
.
Now we can filter based on the index to throw out the values we don't want.
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)
yields [(0, 2), (2, 4), (4, 8)]
.
And we can map out the indexes.
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)
yields [2, 4, 8]
.
Stunningly ugly and inefficient. I'm not sure why anyone is teaching you to write code this way. Feel free to make it extra ugly by removing the newlines.
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))))));