<div dir="ltr">If you care about performance you may - I haven't benchmarked - want to use Vector instead of lists here since that's what aeson uses internally. Then it's pretty handy that you can still use forM_.<div><br></div><div>It's possible that the list pattern deconstruction and list construction gets optimized away, my gut says you need -O2 for that to happen. Here's a good explanation on how to dump and read core so you can check for yourself what happens in this case: <a href="http://stackoverflow.com/questions/6121146/reading-ghc-core">http://stackoverflow.com/questions/6121146/reading-ghc-core</a> . Either way it's definitiely not less efficient to annotate the type instead. You don't need ScopedTypeVariables here, you can write the type inside an expression instead: `forM (objs :: Type) [...]`</div><div><br></div><div>HTH,</div><div>Adam</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 15, 2015 at 7:16 PM, Amit Aryeh Levy <span dir="ltr"><<a href="mailto:amit@amitlevy.com" target="_blank">amit@amitlevy.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I've been running into a relatively small but frequent annoyance with<br>
base >= 4.8 (GHC 7.10). `Control.Monad.foldM_`, `Control.Monad.mapM_`<br>
and `Control.Monad.forM_` are generalized traverse over any `Foldable a`<br>
rather than just arrays (`[a]`).<br>
<br>
 This is great, except I'm finding that, for a lot of my code that works<br>
well in previous versions, I need to specialize the argument to `[a]`<br>
now. If other people are encoutering a similar patter, I wonder what are<br>
your best practices for doing this: ScopedTypeVariables? Deconstruct the<br>
reconstruct the array? ...<br>
<br>
 The most common example is when I deserialize a JSON array with aeson<br>
and want to traverse over that array (say, to store the objects to a DB):<br>
<br>
 ```<br>
let objArray = eitherDecode myjson<br>
case objArray of<br>
    Left err -> ...<br>
    Right (objs :: [MyObjType]) -><br>
        forM_ objs $ \obj -> saveToDb obj<br>
 ```<br>
<br>
​The above fix requires `ScopedTypeVariables` (which is probably OK).<br>
Another option is to deconstruct and reconstruct the list:<br>
<br>
```<br>
Right (o:objs) -><br>
    forM_ (o:objs) $ \obj -> saveToDb obj<br>
```<br>
<br>
Does this get optimized away?<br>
<br>
Penny for your thoughts?<br>
<br>
Cheers!<br>
<span class="HOEnZb"><font color="#888888">Amit<br>
<br>
</font></span><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>