[Haskell-cafe] Store type-class polymorphic values generically

Christopher Done chrisdone
Fri Oct 11 17:36:10 UTC 2013


> Wait... what do you mean "Core cannot generate new names to be exported".

I meant if I add a new name in the Core transformation, that doesn't
change the module's export list as seen by everything outside that
module. Which makes sense, it just means I have to change my approach.

> Maybe you mean that you want your plugin to transform
>
>         module M( f ) where
>           f = e
> into
>         module M( f_ ) where
>           f_ = ...f...
>           f = e
>

No, I meant that

    module M(f) where f = e

should be come

    module M (f, f_) where f = readRefOf f_; f_ = makeSomeRef e

In other words, the API is only changed in that an additional binding
has been exported for each top-level definition to which you can write
(only of the correct type) a new definition. This is something that
you could do manually, write it by hand, but I want it automatic for
any module I load into GHCi!

> That seems pretty drastic, because now the programmer's API for the module has changed.  Are you sure you don't want to do this
>
>         module M( f ) wehre
>           f_ = e
>           f = ...f_...
>
> by renaming the existing f with some local name.

Sure -- but both need to be exported otherwise you can't update the
definition of `f` by writing to `f_`. With both, all other modules
(and the module itself) just refer to `f' as they normally would, it's
just that `f` gets its definition from some kind of mutable cell.

I discussed with Daniel Peebles an approach to this with the new kind
polymorphic Typeable landing in GHC 7.8, in which I could safely write
functions in and out with Fun from HList:
http://code.haskell.org/~aavogt/HList/docs/HList/Data-HList-FakePrelude.html#t:Fun
Hypothetically I can use bog standard Typeable deriving for that type,
and actually use Data.Dynamic to store all functions, using
fromDynamic :: a -> Maybe safe coercion. Don't get me wrong, I don't
want the plugin to break any APIs or do anything unsafe (beyond using
unsafePerformIO to hold a Map Name Dynamic or so), I just want
in-place update of IO-ish actions. I'm compiling GHC from Git at the
moment to see if this approach is worthwhile.



More information about the Haskell-Cafe mailing list