Search code examples
smlsmlnj

how to step over a list in sml?


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 can't use recursion , i was thinking to use foldl but the problem is how to skip over elements i don't want to use list.nth? i would appriciate little hints ! thank you


Solution

  • One solution to correctly skip elements you don't want in your resulting list, is to add a parameter to your function used to fold your list. The meaning of this parameter is basically "how much items you still want to skip".

    As an example, below is a solution that uses List.foldl. The function used to fold items of the list takes two parameters: the first one is the one discussed above and the second one is the resulting list being constructed.

    fun cutt lst (idx_start, idx_end, interval) = let
        val (_, result) =
            List.foldl
                (fn (x, (0, result)) =>
                    (* no more item to skip => add x to the resulting list *)
                    (interval - 1, x :: result)
                |   (_, (n, result)) =>
                    (* there are still items to skip *)
                    (n - 1, result))
                (idx_start, [])  (* initially we skip idx_start items *)
                lst
    in
        (* items are prepended in the resulting list in reverse order =>
        reverse the list *)
        List.rev result
    end;
                             
    val x = cutt [1, 2, 3, 4, 77, 8, 7] (1, 5, 2);
    

    Of course the function needs to be adapted as it does not take care of the idx_end parameter.