Find index of lowest unique integer in each line of the file
First off, your usage of alter can easily be replaced by insertWith:

counts :: [(Int, Int)] -&gt; IntMap [Int]
counts = foldr f empty
  where f (i,v) = insertWith (const (i:)) v [i]


You could also use fromListWith, which is neater but less efficient due to the need to concatenate lists:

counts :: [(Int, Int)] -&gt; IntMap [Int]
counts = fromListWith (flip (++)) . map (\(i,v) -&gt; (v,[i]))


Second, you could shorten g quite a bit as well using a view:

g a = case minView $ filter ((== 1) . length) a of
        Nothing      -&gt; 0
        Just ([i],_) -&gt; i


Which is also probably slightly less efficient, as it will construct at least a thunk for the rest of the IntMap.

Concerning different approaches - you could make a recursive function that removes all duplicates:

import Data.List
import Data.Ord

dedup :: [(Int,Int)] -&gt; [(Int,Int)]
dedup [] = []
dedup ((i,v):ps)
  | null dups = (i,v):dedup ps
  | otherwise = dedup ndups
  where (dups, ndups) = partition ((==v) . snd) ps

minUnique :: [Int] -&gt; Int
minUnique l
  | null ddups = 0
  | otherwise  = fst $ minimumBy (comparing snd) $ ddups
  where ddups = dedup $ zip [1..] l


Once more this trades for a bit of efficiency, as the traversal in partition makes it O(n²). Not sure whether that can be helped though without involving more complex data structures.