hydra-0.1.1: src/main/haskell/Hydra/Adapters/Coders.hs
-- | Entry point for Hydra's adapter (type/term rewriting) framework.
-- An adapter takes a type expression which is supported in a source language, and rewrites it to a type which is supported by a target language.
-- In parallel, terms conforming to the original type are rewritten. Both levels of the transformation are bidirectional.
module Hydra.Adapters.Coders where
import Hydra.Kernel
import Hydra.CoreDecoding
import Hydra.Adapters.Term
import Hydra.Adapters.UtilsEtc
import qualified Control.Monad as CM
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
adaptType :: (Ord m, Read m, Show m) => Language m -> Type m -> GraphFlow m (Type m)
adaptType targetLang t = do
cx <- getState
let acx = AdapterContext cx hydraCoreLanguage targetLang
ad <- withState acx $ termAdapter t
return $ adapterTarget ad
transformModule :: (Ord m, Read m, Show m)
=> Language m
-> (Term m -> GraphFlow m e)
-> (Module m -> M.Map (Type m) (Coder (Context m) (Context m) (Term m) e) -> [(Element m, TypedTerm m)] -> GraphFlow m d)
-> Module m -> GraphFlow m d
transformModule lang encodeTerm createModule mod = do
pairs <- withSchemaContext $ CM.mapM elementAsTypedTerm els
let types = L.nub (typedTermType <$> pairs)
coders <- codersFor types
createModule mod coders $ L.zip els pairs
where
els = moduleElements mod
codersFor types = do
cdrs <- CM.mapM constructCoder types
return $ M.fromList $ L.zip types cdrs
constructCoder typ = withTrace ("coder for " ++ describeType typ) $ do
cx <- getState
let acx = AdapterContext cx hydraCoreLanguage lang
adapter <- withState acx $ termAdapter typ
coder <- termCoder $ adapterTarget adapter
return $ composeCoders (adapterCoder adapter) coder
where
termCoder _ = pure $ unidirectionalCoder encodeTerm