Rename things such that symantic-document is neater when used with import qualified.
[haskell/symantic.git] / symantic / Language / Symantic / Typing / Show.hs
index 0076224a664c48c45c362eb04d09ff1d1ba690cd..cbd360d534d1180ff549ae2b75f2975f038d07c2 100644 (file)
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Language.Symantic.Typing.Show where
 
-import Data.Map.Strict (Map)
-import Data.Semigroup ((<>))
-import Data.Set (Set)
-import Data.Text (Text)
-import Data.Typeable
-import qualified Data.List as List
-import qualified Data.Map.Strict as Map
-import qualified Data.Set as Set
-import qualified Data.Text as Text
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Builder as TLB
 
+import qualified Language.Symantic.Document as D
 import Language.Symantic.Grammar
-import Language.Symantic.Typing.Kind
-import Language.Symantic.Typing.Variable
 import Language.Symantic.Typing.Type
+import Language.Symantic.Typing.Module
+import Language.Symantic.Typing.Document
 
--- * Type 'Config_showType'
-data Config_showType
- =   Config_showType
- {   config_showType_vars_numbering :: Bool
- }
+showType :: Config_Doc_Type -> Type src vs t -> String
+showType conf ty = TL.unpack $ TLB.toLazyText $ D.plain $ docType conf 0 ty
 
-config_showType :: Config_showType
-config_showType =
-       Config_showType
-        { config_showType_vars_numbering = True }
+showTypeS :: Config_Doc_Type -> Precedence -> Type src vs t -> ShowS
+showTypeS conf pr ty = showString $ TL.unpack (TLB.toLazyText $ D.plain $ docType conf pr ty)
 
-showType :: Config_showType -> Int -> Type src vs t -> String
-showType conf pr ty = showTypeS conf pr ty ""
+showTypes :: Config_Doc_Type -> Types src vs ts -> String
+showTypes conf tys = TL.unpack (TLB.toLazyText $ D.plain $ docTypes conf tys)
 
-showTypeS :: forall src vs t. Config_showType -> Int -> Type src vs t -> ShowS
-showTypeS conf pr ty =
-       let (v2n, _) = varNames conf mempty ty in
-       go v2n (infixB SideL pr, SideL) ty
-       where
-       go ::
-        forall x.
-        (Map IndexVar Name) -> -- names of variables
-        (Infix, Side) ->
-        Type src vs x ->
-        ShowS
-       go _v2n _po c
-        | Just HRefl <- proj_ConstKiTy @Constraint @() c = showString "()"
-       go _v2n _po (TyConst _src _vs c) = showsPrec 11 c
-       go v2n _po (TyVar _src _n v) =
-               let iv = indexVar v in
-               case Map.lookup iv v2n of
-                Nothing -> error "[BUG] showsPrec @Type: variable name missing"
-                Just n -> showString $ Text.unpack n
-       go v2n po (TyApp _ (TyApp _ (TyConst _ _ f@Const{}) a) b)
-        | Just HRefl <- proj_ConstKiTy @Constraint @(()::Constraint) a
-        , Just HRefl <- proj_ConstKi @(K (#>)) @(#>) f =
-               go v2n po b
-        | Just (Fixity2 op) <- fixityOf f =
-               showParen (needsParenInfix po op) $
-               go v2n (op, SideL) a .
-               showString (prettyConst f) .
-               go v2n (op, SideR) b
-               where
-               prettyConst :: forall k c. Const src (c::k) -> String
-               prettyConst c | Just HRefl <- proj_ConstKi @(K (#>)) @(#>) c = " => "
-               prettyConst c | Just HRefl <- proj_ConstKi @(K (#)) @(#) c = ", "
-               prettyConst c@Const{}
-                | r <- typeRepTyCon (typeRep c)
-                , tyConName   r =="#~"
-                , tyConModule r =="Language.Symantic.Typing.Type"
-                -- XXX: module name must be in sync with where (#~) is defined.
-                -- NOTE: cannot use 'proj_ConstKi' here
-                -- because (#~) has a polymorphic kind.
-                = " ~ "
-                | otherwise = ' ' : unParen (show c) ++ " "
-               unParen ('(':s) | ')':s' <- reverse s = reverse s'
-               unParen s = s
-       go v2n po (TyApp _src f a) =
-               let op = infixL 11 in
-               showParen (needsParenInfix po op) $
-               go v2n (op, SideL) f .
-               showChar ' ' .
-               go v2n (op, SideR) a
-       go v2n po (TyFam _src _len fam args) =
-               let op = infixL 11 in
-               showParen (needsParenInfix po op) $
-               showsPrec 11 fam .
-               foldlTys (\t acc ->
-                       showChar ' ' . go v2n (op, SideL) t . acc
-                ) args id
-       
-       -- | Return a 'Map' associating a distinct 'Name'
-       -- for all the variables of the given 'Type'.
-       varNames ::
-        forall x.
-        Config_showType ->
-        (Map IndexVar Name, Names) ->
-        Type src vs x ->
-        (Map IndexVar Name, Names)
-       varNames _cfg st TyConst{} = st
-       varNames cfg st@(v2n, ns) (TyVar _src (NameVar n) v) =
-               let iv = indexVar v in
-               case Map.lookup iv v2n of
-                Just{} -> st
-                Nothing ->
-                       let n' = if config_showType_vars_numbering cfg
-                               then n <> Text.pack (show iv)
-                               else freshifyName ns n in
-                       let v2n' = Map.insert iv n' v2n in
-                       let ns'  = Set.insert n' ns in
-                       (v2n', ns')
-       varNames cfg st (TyApp _src f a) = varNames cfg (varNames cfg st f) a
-       varNames cfg st (TyFam _src _len _fam as) = foldlTys (flip $ varNames cfg) as st
+showTypesS :: Config_Doc_Type -> Types src vs ts -> ShowS
+showTypesS conf tys = showString $ TL.unpack (TLB.toLazyText $ D.plain $ docTypes conf tys)
+
+instance NameTyOf c => Show (Const src c) where
+       showsPrec _p = showString . TL.unpack . TLB.toLazyText . D.plain . docConst mempty
 
 instance Source src => Show (Type src vs t) where
-       showsPrec = showTypeS config_showType
+       showsPrec = showTypeS config_Doc_Type
 instance Source src => Show (TypeK src vs kt) where
        showsPrec p (TypeK t) = showsPrec p t
 instance Source src => Show (TypeVT src) where
@@ -120,41 +35,4 @@ instance Source src => Show (TypeVT src) where
 instance Source src => Show (TypeT src vs) where
        showsPrec p (TypeT t) = showsPrec p t
 instance Source src => Show (Types src vs ts) where
-       showsPrec _p tys = showString "[" . go tys . showString "]"
-               where
-               go :: forall xs. Types src vs xs -> ShowS
-               go TypesZ = showString ""
-               go (TypesS t0 (TypesS t1 ts)) = showsPrec 10 t0 . showString ", " . showsPrec 10 t1 . go ts
-               go (TypesS t ts) = showsPrec 10 t . go ts
-
-showBracket :: Bool -> ShowS -> ShowS
-showBracket b p =  if b then showChar '{' . p . showChar '}' else p
-
--- ** Type 'Name'
-type Name     = Text
-type NameHint = Name
-type Names    = Set Name
-
--- | Return given 'Name' renamed a bit to avoid
--- conflicting with any given 'Names'.
-freshifyName :: Names -> Name -> Name
-freshifyName ns "" = freshName ns
-freshifyName ns n =
-       let ints = [1..] :: [Int] in
-       List.head
-        [ fresh
-        | suffix <- "" : (show <$> ints)
-        , fresh <- [n <> Text.pack suffix]
-        , fresh `Set.notMember` ns
-        ]
-
-freshName :: Names -> Name
-freshName ns = List.head $ poolNames List.\\ Set.toList ns
-
--- | Infinite list of unique 'Name's:
--- @a, b, .., z, a1, b1 .., z1, a2, ..@
-poolNames :: [Name]
-poolNames =
-       [ Text.singleton n     | n <- ['a'..'z'] ] <>
-       [ Text.pack (n:show i) | n <- ['a'..'z']
-                              , i <- [1 :: Int ..] ]
+       showsPrec _ = showTypesS config_Doc_Type