Ideally we would swap the handler in an initializer when the library loads, and this works perfectly in ghc, but not ghci -- which apparently links in libraries in a way where c++ style initializers don't get invoked?
A 'replaceAllocator' IO action that swaps the gmp allocation hook isn't a very Haskelly solution either, because I'd prefer to just have it look like another numeric type.
Dan is currently investigating including a patched copy of MPFR in the haskell package, which doesn't try to use the built-in allocator for the constant cache.
This is where it becomes relevant to the discussion at hand, because it would effectively involve linking in our own copy of MPFR, making distributions unhappy.
But another option would be to unsafePerformIO that initializer, which would add a bit of overhead, going through an indirection to make sure that replaceAllocator had been forced, perhaps it wouldn't be too bad:
Something like:
replaceAllocator :: ()
replaceAllocator = unsafePerformIO replaceAllocatorIO
{-# NOINLINE replaceAllocator #-}
instance (Rounding r, Precision p) => Floating (Fixed r p) where
pi = replaceAllocator `pseq` mpfr_pi ...
This doesn't address general purpose use of third party libraries that happen to internally rely upon GMP, however.
Or rather, if it does, the methodology it would lead to would be one of bringing over all of their internals into Haskell. ;)
-Edward Kmett