{-# OPTIONS_GHC -fno-warn-orphans #-} module Symantic.Parser.Grammar.ObserveSharing ( module Symantic.Parser.Grammar.ObserveSharing , ObserveSharing(..) ) where import Control.Monad (mapM) import Control.Applicative (Applicative(..)) import Data.Eq (Eq(..)) import Data.Function (($), (.)) import Data.Functor ((<$>)) import Data.Hashable (Hashable, hashWithSalt) import Text.Show (Show(..)) import Symantic.Univariant.Letable as Letable import qualified Symantic.Univariant.Trans as Sym import qualified Symantic.Parser.Grammar.Combinators as Comb import qualified Language.Haskell.TH.Syntax as TH -- | Like 'Letable.observeSharing' but type-binding @(letName)@ to 'TH.Name' to help type inference. observeSharing :: ObserveSharing TH.Name repr a -> repr a observeSharing = Letable.observeSharing instance Hashable TH.Name where hashWithSalt s = hashWithSalt s . show -- Combinators semantics for the 'ObserveSharing' interpreter instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Charable repr ) => Comb.Charable (ObserveSharing letName repr) instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Alternable repr ) => Comb.Alternable (ObserveSharing letName repr) instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Applicable repr ) => Comb.Applicable (ObserveSharing letName repr) instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Selectable repr ) => Comb.Selectable (ObserveSharing letName repr) instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Matchable repr ) => Comb.Matchable (ObserveSharing letName repr) where -- Here the default definition does not fit since there is no lift* for its type and thus handles 'bs' itself, -- which is not the transformation wanted. conditional cs bs a b = observeSharingNode $ ObserveSharing $ Comb.conditional cs <$> mapM unObserveSharing bs <*> unObserveSharing a <*> unObserveSharing b instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Foldable repr {- TODO: the following constraints are for the current Foldable, - they will have to be removed when Foldable will have Sym.lift2 as defaults -} , Comb.Applicable repr , Comb.Alternable repr ) => Comb.Foldable (ObserveSharing letName repr) instance ( Letable letName repr , MakeLetName letName , Eq letName , Hashable letName , Comb.Lookable repr ) => Comb.Lookable (ObserveSharing letName repr) -- Combinators semantics for the 'CleanDefs' interpreter instance Comb.Applicable repr => Comb.Applicable (CleanDefs letName repr) instance Comb.Alternable repr => Comb.Alternable (CleanDefs letName repr) instance Comb.Charable repr => Comb.Charable (CleanDefs letName repr) instance Comb.Selectable repr => Comb.Selectable (CleanDefs letName repr) instance Comb.Matchable repr => Comb.Matchable (CleanDefs letName repr) where conditional cs bs a b = CleanDefs $ Comb.conditional cs <$> mapM unCleanDefs bs <*> unCleanDefs a <*> unCleanDefs b instance Comb.Lookable repr => Comb.Lookable (CleanDefs letName repr) instance Comb.Foldable repr => Comb.Foldable (CleanDefs letName repr) where chainPre = Sym.lift2 Comb.chainPre chainPost = Sym.lift2 Comb.chainPost