Hi, this is related to http://hackage.haskell.org/trac/ghc/wiki/NewtypeWrappers#Proposal3. I tried to hack up a little prototype of this, and this “works” now:
import GHC.NT newtype Age = Age Int deriving Show ageNT :: NT Age Int ageNT = createNT newtype MyList a = MyList [a] deriving Show myListNT :: NT (MyList a) [a] myListNT = createNT main = do let n = 1 :: Int let a = coerce (sym ageNT) 1 let l1 = [a] let l2 = coerce (listNT ageNT) l1 let l3 = coerce (sym myListNT) l2 print a print l2 print l3 will print Age 1 [1] MyList [1] and no unsafeCoerce and no map is used in the production of this output. The GHC.NT module provides: data NT a b coerce :: NT a b -> a -> b refl :: NT a a sym :: NT a b -> NT b a trans :: NT a b -> NT b c -> NT a c createNT :: NT a b listNT :: NT a b -> NT [a] [b] where createNT takes the place of the "deriving foo :: NT a b" syntax: At compile time, it is checked if its first type argument is a newtype of the second, and the corresponding coercion is inserted, otherwise an error is (well, will be) printed. The idea is that these coercions will be guaranteed to be free (or almost free; I am not sure if the coercion witness (NT a b) will actually be optimized away). The prototype can be found at https://github.com/nomeata/nt-coerce and is implemented as a GHC plugin compatible with GHC 7.6.3 (I chose this route as it means not having to compile GHC). You can check if it works for you via $ ghc -dcore-lint -package ghc --make test.hs && ./test The code itself is, well, at most prototype code quality and contains quite a number of hacks and other warts, mostly due to my inexperience with GHC hacking, and I could make use of some advice. Some more concrete questions: * How do I look up a module (here GHC.NT.Type) and a name therein (NT) in CoreM? I tried to go via getOrigNameCache, but passing the ModuleName name to lookupModuleEnv yielded Nothing, although it seems to me to be precisely the same name that I find in moduleEnvKeys. If I take the ModuleName from that list, it works. Similar problems with the OccEnv. Please see https://github.com/nomeata/nt-coerce/blob/edef9f4d4889dde651bb086e76c576f84e8f8aec/GHC/NT/Plugin.hs#L99 for what I tried (and how I worked around it). This work-around also prevents building the package with cabal right now. * I did not find generic Core traversal functions like traverse :: (Monad m) => (Expr a -> m (Maybe (Expr a))) -> Expr a -> m (Expr a) which I defined in https://github.com/nomeata/nt-coerce/blob/edef9f4d4889dde651bb086e76c576f84e8f8aec/GHC/NT/Plugin.hs#L231. Are such traversals re-implemented everywhere or did I just not search well enough? * On the core level, once I have a TyCon, I also have all DataCons available. Is there already code present that checks if the currently compiled module really should see the data constructors, i.e. if they are exported? I see code in normaliseFfiType, but that seems to be integrated in the type checker, and it seems I need a GlobalRdrEnv; can I get such a thing in a Core2Core pass? Thanks, Joachim -- Joachim “nomeata” Breitner m...@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nome...@joachim-breitner.de • GPG-Key: 0x4743206C Debian Developer: nome...@debian.org
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users