Add colorable and decorable.
[haskell/symantic.git] / symantic-lib / Language / Symantic / Lib / Enum.hs
index 324673193afaae58e1d98ffdcc11361029107e66..3c324f0b30c8ea7c2362b6ef628a6301596cff1d 100644 (file)
 -- | Symantic for 'Enum'.
 module Language.Symantic.Lib.Enum where
 
-import Control.Monad (liftM)
-import Data.Proxy
-import Data.Type.Equality ((:~:)(Refl))
 import Prelude (Enum)
 import Prelude hiding (Enum(..))
-import qualified Data.Function as Fun
 import qualified Prelude
 
-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)
+import Language.Symantic.Lib.Int (tyInt)
 
 -- * Class 'Sym_Enum'
+type instance Sym Enum = Sym_Enum
 class Sym_Enum term where
        toEnum   :: Enum a => term Int -> term a
        fromEnum :: Enum a => term a -> term Int
        succ     :: Enum a => term a -> term a
        pred     :: Enum a => term a -> term a
        
-       default succ     :: (Trans t term, Enum a) => t term a -> t term a
-       default pred     :: (Trans t term, Enum a) => t term a -> t term a
-       default toEnum   :: (Trans t term, Enum a) => t term Int -> t term a
-       default fromEnum :: (Trans t term, Enum a) => t term a -> t term Int
+       default succ     :: Sym_Enum (UnT term) => Trans term => Enum a => term a -> term a
+       default pred     :: Sym_Enum (UnT term) => Trans term => Enum a => term a -> term a
+       default toEnum   :: Sym_Enum (UnT term) => Trans term => Enum a => term Int -> term a
+       default fromEnum :: Sym_Enum (UnT term) => Trans term => Enum a => term a -> term Int
        
-       toEnum   = trans_map1 toEnum
-       fromEnum = trans_map1 fromEnum
-       succ     = trans_map1 succ
-       pred     = trans_map1 pred
+       toEnum   = trans1 toEnum
+       fromEnum = trans1 fromEnum
+       succ     = trans1 succ
+       pred     = trans1 pred
 
-type instance Sym_of_Iface (Proxy Enum) = Sym_Enum
-type instance TyConsts_of_Iface (Proxy Enum) = Proxy Enum ': TyConsts_imported_by (Proxy Enum)
-type instance TyConsts_imported_by (Proxy Enum) =
- '[ Proxy Int
- ]
+-- Interpreting
+instance Sym_Enum Eval where
+       toEnum   = eval1 Prelude.toEnum
+       fromEnum = eval1 Prelude.fromEnum
+       succ     = eval1 Prelude.succ
+       pred     = eval1 Prelude.pred
+instance Sym_Enum View where
+       toEnum   = view1 "toEnum"
+       fromEnum = view1 "fromEnum"
+       succ     = view1 "succ"
+       pred     = view1 "pred"
+instance (Sym_Enum r1, Sym_Enum r2) => Sym_Enum (Dup r1 r2) where
+       toEnum   = dup1 @Sym_Enum toEnum
+       fromEnum = dup1 @Sym_Enum fromEnum
+       succ     = dup1 @Sym_Enum succ
+       pred     = dup1 @Sym_Enum pred
 
-instance Sym_Enum HostI where
-       toEnum   = liftM Prelude.toEnum
-       fromEnum = liftM Prelude.fromEnum
-       succ     = liftM Prelude.succ
-       pred     = liftM Prelude.pred
-instance Sym_Enum TextI where
-       toEnum   = textI1 "toEnum"
-       fromEnum = textI1 "fromEnum"
-       succ     = textI1 "succ"
-       pred     = textI1 "pred"
-instance (Sym_Enum r1, Sym_Enum r2) => Sym_Enum (DupI r1 r2) where
-       toEnum   = dupI1 @Sym_Enum toEnum
-       fromEnum = dupI1 @Sym_Enum fromEnum
-       succ     = dupI1 @Sym_Enum succ
-       pred     = dupI1 @Sym_Enum pred
+-- Transforming
+instance (Sym_Enum term, Sym_Lambda term) => Sym_Enum (BetaT term)
 
-instance
- ( Read_TyNameR TyName cs rs
- , Inj_TyConst cs Enum
- ) => Read_TyNameR TyName cs (Proxy Enum ': rs) where
-       read_TyNameR _cs (TyName "Enum") k = k (ty @Enum)
-       read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
-instance Show_TyConst cs => Show_TyConst (Proxy Enum ': cs) where
-       show_TyConst TyConstZ{} = "Enum"
-       show_TyConst (TyConstS c) = show_TyConst c
+-- Typing
+instance NameTyOf Enum where
+       nameTyOf _c = ["Enum"] `Mod` "Enum"
+instance FixityOf Enum
+instance ClassInstancesFor Enum
+instance TypeInstancesFor Enum
 
-instance Proj_TyConC cs (Proxy Enum)
-data instance TokenT meta (ts::[*]) (Proxy Enum)
- = Token_Term_Enum_fromEnum (EToken meta ts)
- | Token_Term_Enum_toEnum   (EToken meta '[Proxy Token_Type])
- | Token_Term_Enum_succ     (EToken meta ts)
- | Token_Term_Enum_pred     (EToken meta ts)
-deriving instance (Eq meta, Eq_Token meta ts) => Eq (TokenT meta ts (Proxy Enum))
-deriving instance (Show meta, Show_Token meta ts) => Show (TokenT meta ts (Proxy Enum))
+-- Compiling
+instance Gram_Term_AtomsFor src ss g Enum
+instance (Source src, SymInj ss Enum) => ModuleFor src ss Enum where
+       moduleFor = ["Enum"] `moduleWhere`
+        [ "succ"     := teEnum_succ
+        , "pred"     := teEnum_pred
+        , "toEnum"   := teEnum_toEnum
+        , "fromEnum" := teEnum_fromEnum
+        ]
 
-instance -- CompileI
- ( Read_TyName TyName cs
- , Inj_TyConst        cs Enum
- , Inj_TyConst        cs (->)
- , Inj_TyConst        cs Int
- , Proj_TyCon         cs
- , Compile cs is
- ) => CompileI cs is (Proxy Enum) where
-       compileI tok ctx k =
-               case tok of
-                Token_Term_Enum_toEnum tok_ty_a ->
-                       -- toEnum :: Enum a => Int -> a
-                       compile_Type tok_ty_a $ \(ty_a::Type cs a) ->
-                       check_Kind
-                        (At Nothing SKiType)
-                        (At (Just tok_ty_a) $ kind_of ty_a) $ \Refl ->
-                       check_TyCon (At (Just tok_ty_a) (ty @Enum :$ ty_a)) $ \TyCon ->
-                       k (ty @Int ~> ty_a) $ Term $
-                               Fun.const $ lam toEnum
-                Token_Term_Enum_fromEnum tok_a ->
-                       -- fromEnum :: Enum a => a -> Int
-                       compile tok_a ctx $ \ty_a (Term a) ->
-                       check_TyCon (At (Just tok_a) (ty @Enum :$ ty_a)) $ \TyCon ->
-                       k (ty @Int) $ Term $
-                               \c -> fromEnum (a c)
-                Token_Term_Enum_succ tok_a -> op1_from tok_a succ
-                Token_Term_Enum_pred tok_a -> op1_from tok_a pred
-               where
-               op1_from tok_a
-                (op::forall term a. (Sym_Enum term, Enum a)
-                        => term a -> term a) =
-                -- succ :: Enum a => a -> a
-                -- pred :: Enum a => a -> a
-                       compile tok_a ctx $ \ty_a (Term x) ->
-                       check_TyCon (At (Just tok_a) (ty @Enum :$ ty_a)) $ \TyCon ->
-                       k ty_a $ Term $
-                        \c -> op (x c)
-instance -- TokenizeT
- Inj_Token meta ts Enum =>
- TokenizeT meta ts (Proxy Enum) where
-       tokenizeT _t = mempty
-        { tokenizers_infix = tokenizeTMod []
-                [ tokenize1 "succ" infixN5 Token_Term_Enum_succ
-                , tokenize1 "pred" infixN5 Token_Term_Enum_pred
-                , (TeName "toEnum",) ProTok_Term
-                        { protok_term = \meta -> ProTokPi $ \a ->
-                               ProTok $ inj_EToken meta $ Token_Term_Enum_toEnum a
-                        , protok_fixity = infixN5
-                        }
-                , tokenize1 "fromEnum" infixN5 Token_Term_Enum_fromEnum
-                ]
-        }
-instance Gram_Term_AtomsT meta ts (Proxy Enum) g
+-- ** 'Type's
+tyEnum :: Source src => Type src vs a -> Type src vs (Enum a)
+tyEnum a = tyConstLen @(K Enum) @Enum (lenVars a) `tyApp` a
+
+-- ** 'Term's
+teEnum_toEnum :: TermDef Enum '[Proxy a] (Enum a #> (Int -> a))
+teEnum_toEnum = Term (tyEnum a0) (tyInt ~> a0) $ teSym @Enum $ lam1 toEnum
+
+teEnum_fromEnum :: TermDef Enum '[Proxy a] (Enum a #> (a -> Int))
+teEnum_fromEnum = Term (tyEnum a0) (a0 ~> tyInt) $ teSym @Enum $ lam1 fromEnum
+
+teEnum_succ, teEnum_pred :: TermDef Enum '[Proxy a] (Enum a #> (a -> a))
+teEnum_succ = Term (tyEnum a0) (a0 ~> a0) $ teSym @Enum $ lam1 succ
+teEnum_pred = Term (tyEnum a0) (a0 ~> a0) $ teSym @Enum $ lam1 pred