
In my (limited) experience, there are two main solutions to this kind of
problem:
- Dependency-injection, i.e. add the MVar as an explicit parameter to
every function you use it in. This is ideal, but it's often a little
cumbersome.
- unsafePerformIO, i.e. just initialize it globally. I've never really
had issues with this approach, if used sparingly and appropriately.
This might also be relevant:
http://www.haskell.org/haskellwiki/Global_variables
Hope that helps!
On Thu, Apr 17, 2014 at 10:34 AM, Brian Hurt
Thanks. This helps. I was right to mistrust the unsafePerformIO "solution". :-) What Haskell was telling me is that I need to think about the scope of the identifiers I'm allocating, and what guarantees I'm making.
On Thu, Apr 17, 2014 at 10:26 AM, Danny Gratzer
wrote: New `MVar` has to return a different memory location every time and this is noticeable, it's not referentially transparent.
Consider what would happen if we made the transformation
let a = newMVar 0 let b = newMVar 0 putMVar a 1 readMVar b
to
let a = newMVar 0 b = a ...
If newMVar was referentially transparent, we can automatically share any of it's calls with same arguments since they're supposed to return the same thing everytime. Since it's not referentially transparent, back into the IO monad it goes.
Also if you do that toplevel counter trick, you want NoInline otherwise GHC might just inline it at each occurrence and you'll end up with separate counters.
Cheers, Danny Gratzer
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe