Make stack flags customizable in GNUmakefile.
[haskell/symantic.git] / symantic-lib / Language / Symantic / Lib / Semigroup.hs
index 3c83e187de453e9171efa02325784a6271a9d26a..e6fb6f5eca87117da281b01a8ca3bf5e503e7632 100644 (file)
@@ -3,90 +3,60 @@
 -- | Symantic for 'Semigroup'.
 module Language.Symantic.Lib.Semigroup where
 
-import Control.Monad
 import Data.Semigroup (Semigroup)
 import qualified Data.Semigroup as Semigroup
-import Data.Monoid (mempty)
-import Data.Proxy
 
-import Language.Symantic.Parsing
-import Language.Symantic.Typing
-import Language.Symantic.Compiling
-import Language.Symantic.Interpreting
-import Language.Symantic.Transforming
-import Language.Symantic.Lib.Lambda
+import Language.Symantic
+import Language.Symantic.Lib.Function (a0, b1)
+import Language.Symantic.Lib.Integral (tyIntegral)
 
 -- * Class 'Sym_Semigroup'
+type instance Sym Semigroup = Sym_Semigroup
 class Sym_Semigroup term where
        (<>)   :: Semigroup a => term a -> term a -> term a
        stimes :: (Semigroup a, Integral b) => term b -> term a -> term a
        -- sconcat :: NonEmpty a -> a
-       default (<>)   :: (Trans t term, Semigroup a) => t term a -> t term a -> t term a
-       default stimes :: (Trans t term, Semigroup a, Integral b) => t term b -> t term a -> t term a
-       (<>)   = trans_map2 (<>)
-       stimes = trans_map2 stimes
+       default (<>)   :: Sym_Semigroup (UnT term) => Trans term => Semigroup a => term a -> term a -> term a
+       default stimes :: Sym_Semigroup (UnT term) => Trans term => Semigroup a => Integral b => term b -> term a -> term a
+       (<>)   = trans2 (<>)
+       stimes = trans2 stimes
 
-type instance Sym_of_Iface (Proxy Semigroup) = Sym_Semigroup
-type instance TyConsts_of_Iface (Proxy Semigroup) = Proxy Semigroup ': TyConsts_imported_by Semigroup
-type instance TyConsts_imported_by Semigroup = '[Proxy Integral]
+-- Interpreting
+instance Sym_Semigroup Eval where
+       (<>)   = eval2 (Semigroup.<>)
+       stimes = eval2 Semigroup.stimes
+instance Sym_Semigroup View where
+       (<>)   = viewInfix "-" (infixR 6)
+       stimes = view2 "stimes"
+instance (Sym_Semigroup r1, Sym_Semigroup r2) => Sym_Semigroup (Dup r1 r2) where
+       (<>)   = dup2 @Sym_Semigroup (<>)
+       stimes = dup2 @Sym_Semigroup stimes
 
-instance Sym_Semigroup HostI where
-       (<>)   = liftM2 (Semigroup.<>)
-       stimes = liftM2 Semigroup.stimes
-instance Sym_Semigroup TextI where
-       (<>)   = textI_infix "-" (infixR 6)
-       stimes = textI2 "stimes"
-instance (Sym_Semigroup r1, Sym_Semigroup r2) => Sym_Semigroup (DupI r1 r2) where
-       (<>)   = dupI2 @Sym_Semigroup (<>)
-       stimes = dupI2 @Sym_Semigroup stimes
+-- Transforming
+instance (Sym_Semigroup term, Sym_Lambda term) => Sym_Semigroup (BetaT term)
 
-instance
- ( Read_TyNameR TyName cs rs
- , Inj_TyConst cs Semigroup
- ) => Read_TyNameR TyName cs (Proxy Semigroup ': rs) where
-       read_TyNameR _cs (TyName "Semigroup") k = k (ty @Semigroup)
-       read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
-instance Show_TyConst cs => Show_TyConst (Proxy Semigroup ': cs) where
-       show_TyConst TyConstZ{} = "Semigroup"
-       show_TyConst (TyConstS c) = show_TyConst c
+-- Typing
+instance NameTyOf Semigroup where
+       nameTyOf _c = ["Semigroup"] `Mod` "Semigroup"
+instance FixityOf Semigroup
+instance ClassInstancesFor Semigroup
+instance TypeInstancesFor Semigroup
 
-instance Proj_TyConC cs (Proxy Semigroup)
-data instance TokenT meta (ts::[*]) (Proxy Semigroup)
- = Token_Term_Semigroup_sappend (EToken meta ts)
- | Token_Term_Semigroup_stimes  (EToken meta ts) (EToken meta ts)
-deriving instance (Eq meta, Eq_Token meta ts) => Eq (TokenT meta ts (Proxy Semigroup))
-deriving instance (Show meta, Show_Token meta ts) => Show (TokenT meta ts (Proxy Semigroup))
-instance -- CompileI
- ( Read_TyName TyName (TyConsts_of_Ifaces is)
- , Inj_TyConst (TyConsts_of_Ifaces is) Semigroup
- , Inj_TyConst (TyConsts_of_Ifaces is) (->)
- , Inj_TyConst (TyConsts_of_Ifaces is) Integral
- , Proj_TyCon  (TyConsts_of_Ifaces is)
- , Compile is
- ) => CompileI is (Proxy Semigroup) where
-       compileI tok ctx k =
-               case tok of
-                Token_Term_Semigroup_sappend tok_a ->
-                       -- (<>) :: Semigroup a => a -> a -> a
-                       compileO tok_a ctx $ \ty_a (TermO x) ->
-                       check_TyCon (At (Just tok_a) (ty @Semigroup :$ ty_a)) $ \TyCon ->
-                       k (ty_a ~> ty_a) $ TermO $
-                        \c -> lam $ \y -> (<>) (x c) y
-                Token_Term_Semigroup_stimes tok_b tok_a ->
-                       -- stimes :: (Semigroup a, Integral b) => b -> a -> a
-                       compileO tok_b ctx $ \ty_b (TermO b) ->
-                       compileO tok_a ctx $ \ty_a (TermO a) ->
-                       check_TyCon (At (Just tok_a) (ty @Integral :$ ty_b)) $ \TyCon ->
-                       check_TyCon (At (Just tok_a) (ty @Semigroup :$ ty_a)) $ \TyCon ->
-                       k ty_a $ TermO $
-                        \c -> stimes (b c) (a c)
-instance -- TokenizeT
- Inj_Token meta ts Semigroup =>
- TokenizeT meta ts (Proxy Semigroup) where
-       tokenizeT _t = mempty
-        { tokenizers_infix = tokenizeTMod []
-                [ tokenize1 "<>" (infixR 6)  Token_Term_Semigroup_sappend
-                , tokenize2 "stimes" infixN5 Token_Term_Semigroup_stimes
-                ]
-        }
-instance Gram_Term_AtomsT meta ts (Proxy Semigroup) g
+-- Compiling
+instance Gram_Term_AtomsFor src ss g Semigroup
+instance (Source src, SymInj ss Semigroup) => ModuleFor src ss Semigroup where
+       moduleFor = ["Semigroup"] `moduleWhere`
+        [ "<>" `withInfixR` 6 := teSemigroup_sappend
+        , "stimes" := teSemigroup_stimes
+        ]
+
+-- ** 'Type's
+tySemigroup :: Source src => Type src vs a -> Type src vs (Semigroup a)
+tySemigroup a = tyConstLen @(K Semigroup) @Semigroup (lenVars a) `tyApp` a
+
+-- ** 'Term's
+teSemigroup_sappend :: TermDef Semigroup '[Proxy a] (Semigroup a #> (a -> a -> a))
+teSemigroup_sappend = Term (tySemigroup a0) (a0 ~> a0 ~> a0) $ teSym @Semigroup $ lam2 (<>)
+
+teSemigroup_stimes :: TermDef Semigroup '[Proxy a, Proxy b] (Semigroup a # Integral b #> (b -> a -> a))
+teSemigroup_stimes = Term (tySemigroup a0 # tyIntegral b1) (b1 ~> a0 ~> a0) $ teSym @Semigroup $ lam2 stimes