-- | The functions in here auto-create suitable algebra product functions from -- a signature. Currently, functions @<**@ are supported which have scalar -- results in the first variable. -- -- TODO If we want to support classified DP, we shall also need @**<@ -- generating vector-results given a vector result, followed by a scalar -- result. -- -- TODO Then we also need @***@ handling the case of vector-to-vector results. -- -- TODO note the comments in @buildBacktrackingChoice@ module ADP.Fusion.Core.TH ( makeAlgebraProduct , (<||) , (**>) ) where import Data.List import Data.Tuple.Select import Language.Haskell.TH import Language.Haskell.TH.Syntax import qualified Data.Vector.Fusion.Stream.Monadic as SM import ADP.Fusion.Core.TH.Backtrack -- (makeBacktrackingProductInstance,(<||)) import ADP.Fusion.Core.TH.Common (getRuleResultType) makeAlgebraProduct = makeProductInstances {- -- | Create the algebra product function from a signature type constructor. -- -- TODO make the resulting function INLINE -- -- TODO compare @synTypes@ with the stream argument types of all @hs@ (via their -- @hns@ names). If there is a mismatch, then either not all non-terminal types -- have a corresponding choice function or vice versa. makeAlgebraProductH :: [Name] -> Name -> Q [Dec] makeAlgebraProductH hns nm = do rnm <- reify nm case rnm of TyConI (DataD ctx tyConName args cs d) -> case cs of -- we analyze the accessor functions and look for the objective function -- accessor. It's stream parameter is the type of the non-terminal. -- Everything else in accessors are terminal parameters. [RecC dataConName fs'] -> do -- split @fs@ into functions applied to rule RHSs and choice functions (@hs@) let (fs,hs) = partition ((`notElem` hns) . sel1) fs' -- the result types of the @fs@ are the types of the non-terminal symbols let synTypes = nub . map getRuleResultType $ fs -- funStream <- funD (mkName "<**") [genClauseStream dataConName fs' fs hs] funList <- funD (mkName "<||") [genClauseBacktrack dataConName fs' fs hs] return -- [ funStream [ funList , PragmaD $ InlineP (mkName "<||") Inline FunLike AllPhases ] _ -> fail "more than one data ctor" _ -> fail "unsupported data type" -- | Creates a class for each type of product and instances for each -- signature. makeClassyProducts :: Name -> Q [Dec] makeClassyProducts conName = do c <- lookupValueName "BacktrackingProduct" case c of Nothing -> error "need to create class now and add instance" Just cl -> error "add instance" return [] -}