Question

Im trying to create a haskell function where all the indices of an occurence of a value in a list are returned as a list, so like

indices 3 [1,2,3,3,7]

gives [2, 3] as output. I am very new to Haskell and couldnt find something useful. I tried using filter, but all i got working is getting a list of [3, 3] but not the actual indices. It would be cool if you could give me a little hint.

Was it helpful?

Solution

This is a pretty common pattern in functional programming, sometimes called decorate-process-undecorate. The idea is that you want to attach some extra information to each of the elements in your list, filter using a slightly altered version of the filter you would have done normally, then strip that extra information away.

indicies n = undecorate . filter predicate . decorate where
  decorate   = ...
  predicate  = ...
  undecodate = ...

When trying to code decorate I suggest taking a look at the function zip:

zip :: [a] -> [b] -> [(a, b)]

Consider its effect on infinite lists, too, such as repeat 1 or [1,3,...]. When trying to code undecorate you'll likely want to map:

map :: (a -> b) -> [a] -> [b]

Finally, don't worry about the efficiency of this process. In a strict language, decorate-filter-undecorate might require 3 traversals of the list. In a non-strict language like Haskell the compiler will automatically merge the 3 inner loops into a single one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top