1

Let's say I have some v, which is both Applicative and also Traversable. How can I get a v with the indices of v? For a concrete example, consider V3 from Linear. I want V3 0 1 2.

One way is to use mapAccumL with a dummy, for example:

snd $ T.mapAccumL 
    (\idx _ -> (idx + 1, idx)) 
    0 (pure "") :: V3 Int

But the (pure "") dummy feels inelegant. How can we do this in a more elegant way?

yong
  • 3,583
  • 16
  • 32
  • 1
    Relevant: [How would I use `lens` in Haskell to duplicate Python's `enumerate`?](http://stackoverflow.com/questions/29125149/how-would-i-use-lens-in-haskell-to-duplicate-pythons-enumerate) – dfeuer Mar 21 '15 at 06:57
  • 4
    What's the deal with the empty string? If you want a "nothing interesting" value, the canonical choice is `()`. – dfeuer Mar 21 '15 at 07:09
  • The post @dfeuer linked contains several nice alternative approaches, but none of them remove the need for an initial value to give the shape. (But then that question didn't ask for that, either.) – Ørjan Johansen Mar 21 '15 at 07:12

1 Answers1

2

You are not going to escape using pure if you are doing this with just Applicative and Traversable. It's the only function in those classes which gives you a value of your type without already having one.

Also, your dummy determines the shape of the value you construct. Consider a type such as lists, where not all values have the same shape: How do you choose between constructing [0], [0,1] or [0,1,2]? (A pure-based dummy gives you the first one.)

Ørjan Johansen
  • 18,119
  • 3
  • 43
  • 53