-- |-- Module: Data.Dynamic.Reify-- Copyright: (c) 2009 Andy Gill-- License: BSD3---- Maintainer: Andy Gill <andygill@ku.edu>-- Stability: unstable-- Portability: ghc---- This is a 'Dynamic' version of 'Data.Reify', that can reify nodes-- of different types inside a sigle graph, provided they unify to-- a common representation.-- {-# LANGUAGE UndecidableInstances, TypeFamilies, RankNTypes, ExistentialQuantification, DeriveDataTypeable, RelaxedPolyRec, FlexibleContexts #-}moduleData.Dynamic.Reify(MuRef(..),moduleData.Reify.Graph,reifyGraph,)whereimportControl.Concurrent.MVarimportControl.MonadimportSystem.Mem.StableNameimportData.IntMapasMimportData.DynamicimportControl.ApplicativeimportData.Reify.Graph-- | 'MuRef' is a class that provided a way to reference into a specific type,-- and a way to map over the deferenced internals.classMuRefawheretypeDeRefa::*->*mapDeRef::(Applicativef)=>(forallb.(MuRefb,Typeableb,DeRefa~DeRefb)=>b->fu)->a->f(DeRefau)-- | 'reifyGraph' takes a data structure that admits 'MuRef', and returns a 'Graph' that contains-- the dereferenced nodes, with their children as 'Int' rather than recursive values.reifyGraph::(MuRefs,Typeables)=>s->IO(Graph(DeRefs))reifyGraphm=dort1<-newMVarM.emptyrt2<-newMVar[]uVar<-newMVar0root<-findNodesrt1rt2uVarmpairs<-readMVarrt2return(Graphpairsroot)findNodes::(MuRefs,Typeables)=>MVar(IntMap[(Dynamic,Int)])-- Dynamic of StableNames->MVar[(Int,DeRefsInt)]->MVarInt->s->IOIntfindNodesrt1rt2uVarj|j`seq`True=dost<-makeStableNamejtab<-takeMVarrt1casemylookupsttabofJustvar->doputMVarrt1tabreturn$varNothing->dovar<-newUniqueuVarputMVarrt1$M.insertWith(++)(hashStableNamest)[(toDynst,var)]tabres<-mapDeRef(findNodesrt1rt2uVar)jtab'<-takeMVarrt2putMVarrt2$(var,res):tab'returnvarmylookup::(Typeablea)=>StableNamea->IntMap[(Dynamic,Int)]->MaybeIntmylookuphtab=caseM.lookup(hashStableNameh)tabofJusttab2->Prelude.lookup(Justh)[(fromDynamicc,u)|(c,u)<-tab2]Nothing->NothingnewUnique::MVarInt->IOIntnewUniquevar=dov<-takeMVarvarletv'=succvputMVarvarv'returnv'