1
votes

Given a generic list, return a list containing the same objects in a tuple with their index in the list.

For example:

f ["a", "b"];
- val it = [(0,"a") , (1,"b")] : (int * string) list

The function should be a one-liner, meaning no pattern matching, recursion, if/else, helper functions and let/local. So far i could only make a list of indices given the input list:

fun f lst = List.take((foldl (fn (x,list) => [(hd(list)-1)]@list) [length(lst)] (lst)),length(lst));
f [#"a",#"b"];
- val it = [0, 1]: int List.list;

I should add the list items to these indices in a tuple but i'm not sure how to do that.

2

2 Answers

1
votes

Here is a hint for one way to solve it:

1) Using List.sub, create an anonymous function which sends an index i to the pair consisting of i and the lst element at index i.

2) Map this over the result obtained by calling List.tabulate on length lst and the function which sends x to x.

I was able to get this to work (on one line), but the result is ugly compared to a straightforward pattern-matching approach. Other than as a puzzle, I don't see the motivation for disallowing that which makes SML an elegant language.

1
votes

It appears that i forgot the #i operator to access the i'th element of a tuple. The answer is the following:

fun f xs = List.take((foldr (fn (x,list) => [(#1(hd(list))-1,x)]@list) [(length(xs),hd(xs))] (xs)),length(xs));
f (explode "Hello");
- val it = [(0, #"H"), (1, #"e"), (2, #"l"), (3, #"l"), (4, #"o")]: (int * char) List.list;