The problem is in the loop body:
abort to the result of the
HT.lookup action, but the resulting IO actions are then simply discarded by
forM_ as values, without being used or executed.
This is similar to saying:
putStrLn <$> getLine -- has type IO (IO ())
This action yields a separate IO action as its result. Executing it and discarding its result will end up executing only the
getLine, and not the
Correcting this requires using
join, or equivalently using
=<< as the application operator instead of
putStrLn =<< getLine -- has type IO ()
This combines the two actions into a single action, as expected.