SciFlow-0.3.0: src/Scientific/Workflow/Builder/TH.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
module Scientific.Workflow.Builder.TH where
import Language.Haskell.TH
import Control.Applicative ((<$>), (<*>))
import Control.Arrow ((>>>))
import Control.Monad.State
import Data.Default.Class
import qualified Data.HashMap.Strict as M
import Scientific.Workflow.Types
import Scientific.Workflow.Utils (fileExist)
import Scientific.Workflow.Builder
mkWorkflow :: String -- ^ the name of workflow
-> Builder ()
-> Q [Dec]
mkWorkflow name builder = do
-- st <- runIO $ readWorkflowState config $ fst $ unzip nd
nodeDec <- defineNodes nd -- ^ define node functions
-- construct workflow
wfDec <- [d| $( varP $ mkName name ) = $( fmap ListE $ mapM (linkFrom table) leafNodes )
|]
return $ nodeDec ++ wfDec
where
builderSt = execState builder $ B [] []
leafNodes = map (flip (M.lookupDefault undefined) table) . leaves .
fromFactors . snd . unzip . _links $ builderSt
table = M.fromList $ _links builderSt
nd = map (\(a,b,_) -> (a,b)) $ _nodes builderSt
defineNodes :: [(String, ExpQ)] -> Q [Dec]
defineNodes nodes = fmap concat $ mapM f nodes
where
f (l, fn) = [d| $(varP $ mkName l) = proc l $(fn) |]
{-# INLINE defineNodes #-}
-- | Start linking processors from a given node
linkFrom :: M.HashMap String Factor
-> Factor
-> Q Exp
linkFrom table nd = [| Workflow $(go nd) |]
where
expand x = go $ M.lookupDefault (S x) x table
go (S a) = varE $ mkName a
go (L a t) = [| $(expand a) >>> $(go $ S t) |]
go (L2 (a,b) t) = [| (,)
<$> $(expand a)
<*> $(expand b)
>>> $(go $ S t) |]
go (L3 (a,b,c) t) = [| (,,)
<$> $(expand a)
<*> $(expand b)
<*> $(expand c)
>>> $(go $ S t) |]
go (L4 (a,b,c,d) t) = [| (,,,)
<$> $(expand a)
<*> $(expand b)
<*> $(expand c)
<*> $(expand d)
>>> $(go $ S t) |]
go (L5 (a,b,c,d,f) t) = [| (,,,,)
<$> $(expand a)
<*> $(expand b)
<*> $(expand c)
<*> $(expand d)
<*> $(expand f)
>>> $(go $ S t) |]
go (L6 (a,b,c,d,f,e) t) = [| (,,,,,)
<$> $(expand a)
<*> $(expand b)
<*> $(expand c)
<*> $(expand d)
<*> $(expand f)
<*> $(expand e)
>>> $(go $ S t) |]
{-# INLINE linkFrom #-}