Solution (source code)

= Solution

Attach zero-based indices before filtering:
``
findStates :: [State] -> String -> [(State, Integer)]
findStates states str =
  [(state, i) |
     (state, i) <- zip states [0..],
     isPrefix str state]
``
The <zip function> pairs each state with its position in the original sequence. The <list comprehension> retains exactly those pairs satisfying the <prefix> test, preserving their order and their original indices. The declared result makes `[0..]` a stream of `Integer` indices. An empty search string matches every state, including an empty state, because the empty <list> is a <prefix> of every <list>.