{- |
Module      :  ./OWL2/Print.hs
Copyright   :  (c) Heng Jiang, Uni Bremen 2005-2006
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  Christian.Maeder@dfki.de
Stability   :  provisional
Portability :  portable

Pretty printing for the Manchester Syntax of OWL 2.
-}

module OWL2.Print where

import Common.Doc
import Common.DocUtils
import Common.Id
import Common.Keywords
import Common.IRI

import qualified OWL2.AS as AS
import OWL2.MS
import OWL2.Symbols
import OWL2.Keywords
import OWL2.ColonKeywords

import Data.List

instance Pretty AS.Character where
    pretty :: Character -> Doc
pretty = String -> Doc
printCharact (String -> Doc) -> (Character -> String) -> Character -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Character -> String
forall a. Show a => a -> String
show

printCharact :: String -> Doc
printCharact :: String -> Doc
printCharact = String -> Doc
text

printIRI :: IRI -> Doc
printIRI :: IRI -> Doc
printIRI q :: IRI
q
    | ((IRI -> Bool
hasFullIRI IRI
q Bool -> Bool -> Bool
|| IRI -> String
prefixName IRI
q String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["", "owl", "rdfs"])
       Bool -> Bool -> Bool
&& IRI -> Bool
AS.isPredefPropOrClass IRI
q)
       Bool -> Bool -> Bool
|| IRI -> Bool
AS.isDatatypeKey IRI
q = String -> Doc
keyword (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ IRI -> String
AS.getPredefName IRI
q
    | Bool
otherwise = String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ IRI -> String
showIRI IRI
q

printDataIRI :: IRI -> Doc
printDataIRI :: IRI -> Doc
printDataIRI q :: IRI
q = if IRI -> Bool
AS.isDatatypeKey IRI
q then String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ IRI -> String
showIRI (IRI -> String) -> IRI -> String
forall a b. (a -> b) -> a -> b
$ IRI -> IRI
AS.setDatatypePrefix IRI
q
 else IRI -> Doc
printIRI IRI
q

-- | Symbols printing

instance Pretty ExtEntityType where
    pretty :: ExtEntityType -> Doc
pretty ety :: ExtEntityType
ety = case ExtEntityType
ety of
        AnyEntity -> Doc
empty
        EntityType ty :: EntityType
ty -> String -> Doc
keyword (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ EntityType -> String
forall a. Show a => a -> String
show EntityType
ty
        PrefixO -> String -> Doc
keyword "Prefix"

instance Pretty SymbItems where
    pretty :: SymbItems -> Doc
pretty (SymbItems m :: ExtEntityType
m us :: [IRI]
us) = ExtEntityType -> Doc
forall a. Pretty a => a -> Doc
pretty ExtEntityType
m
        Doc -> Doc -> Doc
<+> [IRI] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithCommas [IRI]
us

instance Pretty SymbMapItems where
    pretty :: SymbMapItems -> Doc
pretty (SymbMapItems m :: ExtEntityType
m us :: [(IRI, Maybe IRI)]
us) = ExtEntityType -> Doc
forall a. Pretty a => a -> Doc
pretty ExtEntityType
m
        Doc -> Doc -> Doc
<+> [Doc] -> Doc
sepByCommas
            (((IRI, Maybe IRI) -> Doc) -> [(IRI, Maybe IRI)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ (s :: IRI
s, ms :: Maybe IRI
ms) -> [Doc] -> Doc
sep
                [ IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
s
                , case Maybe IRI
ms of
                    Nothing -> Doc
empty
                    Just t :: IRI
t -> Doc
mapsto Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
t]) [(IRI, Maybe IRI)]
us)

instance GetRange RawSymb -- no position by default

instance Pretty RawSymb where
    pretty :: RawSymb -> Doc
pretty rs :: RawSymb
rs = case RawSymb
rs of
        ASymbol e :: Entity
e -> Entity -> Doc
forall a. Pretty a => a -> Doc
pretty Entity
e
        AnUri u :: IRI
u -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
u
        APrefix p :: String
p -> String -> Doc
forall a. Pretty a => a -> Doc
pretty String
p

cardinalityType :: AS.CardinalityType -> Doc
cardinalityType :: CardinalityType -> Doc
cardinalityType = String -> Doc
keyword (String -> Doc)
-> (CardinalityType -> String) -> CardinalityType -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CardinalityType -> String
AS.showCardinalityType

quantifierType :: AS.QuantifierType -> Doc
quantifierType :: QuantifierType -> Doc
quantifierType = String -> Doc
keyword (String -> Doc)
-> (QuantifierType -> String) -> QuantifierType -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QuantifierType -> String
AS.showQuantifierType

printRelation :: AS.Relation -> Doc
printRelation :: Relation -> Doc
printRelation = String -> Doc
keyword (String -> Doc) -> (Relation -> String) -> Relation -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relation -> String
AS.showRelation

printEquivOrDisjointClasses :: AS.EquivOrDisjoint -> Doc
printEquivOrDisjointClasses :: EquivOrDisjoint -> Doc
printEquivOrDisjointClasses x :: EquivOrDisjoint
x = case EquivOrDisjoint
x of
    AS.Equivalent -> String -> Doc
text "EquivalentClasses:"
    AS.Disjoint -> String -> Doc
text "DisjointClasses:"

printEquivOrDisjointProp :: AS.EquivOrDisjoint -> Doc
printEquivOrDisjointProp :: EquivOrDisjoint -> Doc
printEquivOrDisjointProp e :: EquivOrDisjoint
e = case EquivOrDisjoint
e of
    AS.Disjoint -> String -> Doc
text "DisjointProperties:"
    AS.Equivalent -> String -> Doc
text "EquivalentProperties:"

printPositiveOrNegative :: AS.PositiveOrNegative -> Doc
printPositiveOrNegative :: PositiveOrNegative -> Doc
printPositiveOrNegative x :: PositiveOrNegative
x = case PositiveOrNegative
x of
    AS.Positive -> Doc
empty
    AS.Negative -> String -> Doc
keyword String
notS

printSameOrDifferentInd :: AS.SameOrDifferent -> Doc
printSameOrDifferentInd :: SameOrDifferent -> Doc
printSameOrDifferentInd x :: SameOrDifferent
x = case SameOrDifferent
x of
    AS.Same -> String -> Doc
keyword String
sameIndividualC
    AS.Different -> String -> Doc
keyword String
differentIndividualsC

instance Pretty AS.Entity where
    pretty :: Entity -> Doc
pretty (AS.Entity _ ty :: EntityType
ty e :: IRI
e) = String -> Doc
keyword (EntityType -> String
forall a. Show a => a -> String
show EntityType
ty) Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
e

instance Pretty AS.Literal where
    pretty :: Literal -> Doc
pretty lit :: Literal
lit = case Literal
lit of
        AS.Literal lexi :: String
lexi ty :: TypedOrUntyped
ty -> let
          escapeDQ :: Int -> String -> String
escapeDQ c :: Int
c s :: String
s = case String
s of
            "" -> ""
            h :: Char
h : t :: String
t -> case Char
h of
              '\\' -> Char
h Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
escapeDQ (Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1 :: Int) String
t
              _ | Int -> Bool
forall a. Integral a => a -> Bool
odd Int
c Bool -> Bool -> Bool
|| Char
h Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '"' -> Char
h Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
escapeDQ 0 String
t
              _ -> '\\' Char -> String -> String
forall a. a -> [a] -> [a]
: Char
h Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
escapeDQ 0 String
t
          in String -> Doc
plainText ('"' Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
escapeDQ 0 String
lexi String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\"") Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> case TypedOrUntyped
ty of
            AS.Typed u :: IRI
u -> String -> Doc
keyword String
AS.cTypeS Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> IRI -> Doc
printDataIRI IRI
u
            AS.Untyped tag :: Maybe String
tag -> case Maybe String
tag of
              Nothing -> Doc
empty
              Just tag2 :: String
tag2 -> String -> Doc
text String
asP Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
tag2
        AS.NumberLit f :: FloatLit
f -> String -> Doc
text (FloatLit -> String
forall a. Show a => a -> String
show FloatLit
f)

instance Pretty AS.ObjectPropertyExpression where
    pretty :: ObjectPropertyExpression -> Doc
pretty = ObjectPropertyExpression -> Doc
printObjPropExp

printObjPropExp :: AS.ObjectPropertyExpression -> Doc
printObjPropExp :: ObjectPropertyExpression -> Doc
printObjPropExp obExp :: ObjectPropertyExpression
obExp = case ObjectPropertyExpression
obExp of
    AS.ObjectProp ou :: IRI
ou -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
ou
    AS.ObjectInverseOf iopExp :: ObjectPropertyExpression
iopExp -> String -> Doc
keyword String
inverseS Doc -> Doc -> Doc
<+> ObjectPropertyExpression -> Doc
printObjPropExp ObjectPropertyExpression
iopExp

printFV :: (AS.ConstrainingFacet, AS.RestrictionValue) -> Doc
printFV :: (IRI, Literal) -> Doc
printFV (facet :: IRI
facet, restValue :: Literal
restValue) = String -> Doc
forall a. Pretty a => a -> Doc
pretty (IRI -> String
fromCF IRI
facet) Doc -> Doc -> Doc
<+> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
restValue

fromCF :: AS.ConstrainingFacet -> String
fromCF :: IRI -> String
fromCF f :: IRI
f
    | IRI -> Bool
hasFullIRI IRI
f = IRI -> String
showIRICompact IRI
f String -> String -> String
forall a. Eq a => [a] -> [a] -> [a]
\\ "http://www.w3.org/2001/XMLSchema#"
    | Bool
otherwise = Id -> String
forall a. Show a => a -> String
show (Id -> String) -> Id -> String
forall a b. (a -> b) -> a -> b
$ IRI -> Id
iriPath IRI
f

instance Pretty DatatypeFacet where
    pretty :: DatatypeFacet -> Doc
pretty = String -> Doc
keyword (String -> Doc)
-> (DatatypeFacet -> String) -> DatatypeFacet -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DatatypeFacet -> String
showFacet

-- | Printing the DataRange
instance Pretty AS.DataRange where
    pretty :: DataRange -> Doc
pretty = DataRange -> Doc
printDataRange

printDataRange :: AS.DataRange -> Doc
printDataRange :: DataRange -> Doc
printDataRange dr :: DataRange
dr = case DataRange
dr of
    AS.DataType dtype :: IRI
dtype l :: [(IRI, Literal)]
l -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
dtype Doc -> Doc -> Doc
<+>
      if [(IRI, Literal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(IRI, Literal)]
l then Doc
empty else Doc -> Doc
brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
sepByCommas ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ((IRI, Literal) -> Doc) -> [(IRI, Literal)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (IRI, Literal) -> Doc
printFV [(IRI, Literal)]
l
    AS.DataComplementOf drange :: DataRange
drange -> String -> Doc
keyword String
notS Doc -> Doc -> Doc
<+> DataRange -> Doc
forall a. Pretty a => a -> Doc
pretty DataRange
drange
    AS.DataOneOf constList :: [Literal]
constList -> Doc -> Doc
specBraces (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Literal] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithCommas [Literal]
constList
    AS.DataJunction ty :: JunctionType
ty drlist :: [DataRange]
drlist -> let
      k :: String
k = case JunctionType
ty of
          AS.UnionOf -> String
orS
          AS.IntersectionOf -> String
andS
      in [Doc] -> Doc
fsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
prepPunctuate (String -> Doc
keyword String
k Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
space) ([Doc] -> [Doc]) -> [Doc] -> [Doc]
forall a b. (a -> b) -> a -> b
$ (DataRange -> Doc) -> [DataRange] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map DataRange -> Doc
forall a. Pretty a => a -> Doc
pretty [DataRange]
drlist

-- | Printing the ClassExpression
instance Pretty AS.ClassExpression where
  pretty :: ClassExpression -> Doc
pretty desc :: ClassExpression
desc = case ClassExpression
desc of
   AS.Expression ocUri :: IRI
ocUri -> IRI -> Doc
printIRI IRI
ocUri
   AS.ObjectJunction ty :: JunctionType
ty ds :: [ClassExpression]
ds -> let
      (k :: String
k, p :: ClassExpression -> Doc
p) = case JunctionType
ty of
          AS.UnionOf -> (String
orS, ClassExpression -> Doc
forall a. Pretty a => a -> Doc
pretty)
          AS.IntersectionOf -> (String
andS, ClassExpression -> Doc
printPrimary)
      in [Doc] -> Doc
fsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
prepPunctuate (String -> Doc
keyword String
k Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
space) ([Doc] -> [Doc]) -> [Doc] -> [Doc]
forall a b. (a -> b) -> a -> b
$ (ClassExpression -> Doc) -> [ClassExpression] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ClassExpression -> Doc
p [ClassExpression]
ds
   AS.ObjectComplementOf d :: ClassExpression
d -> String -> Doc
keyword String
notS Doc -> Doc -> Doc
<+> ClassExpression -> Doc
printNegatedPrimary ClassExpression
d
   AS.ObjectOneOf indUriList :: [IRI]
indUriList -> Doc -> Doc
specBraces (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [IRI] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithCommas [IRI]
indUriList
   AS.ObjectValuesFrom ty :: QuantifierType
ty opExp :: ObjectPropertyExpression
opExp d :: ClassExpression
d ->
      ObjectPropertyExpression -> Doc
printObjPropExp ObjectPropertyExpression
opExp Doc -> Doc -> Doc
<+> QuantifierType -> Doc
quantifierType QuantifierType
ty Doc -> Doc -> Doc
<+> ClassExpression -> Doc
printNegatedPrimary ClassExpression
d
   AS.ObjectHasSelf opExp :: ObjectPropertyExpression
opExp ->
      ObjectPropertyExpression -> Doc
printObjPropExp ObjectPropertyExpression
opExp Doc -> Doc -> Doc
<+> String -> Doc
keyword String
selfS
   AS.ObjectHasValue opExp :: ObjectPropertyExpression
opExp indUri :: IRI
indUri ->
      ObjectPropertyExpression -> Doc
forall a. Pretty a => a -> Doc
pretty ObjectPropertyExpression
opExp Doc -> Doc -> Doc
<+> String -> Doc
keyword String
valueS Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
indUri
   AS.ObjectCardinality (AS.Cardinality ty :: CardinalityType
ty card :: Int
card opExp :: ObjectPropertyExpression
opExp maybeDesc :: Maybe ClassExpression
maybeDesc) ->
      ObjectPropertyExpression -> Doc
printObjPropExp ObjectPropertyExpression
opExp Doc -> Doc -> Doc
<+> CardinalityType -> Doc
cardinalityType CardinalityType
ty
        Doc -> Doc -> Doc
<+> String -> Doc
text (Int -> String
forall a. Show a => a -> String
show Int
card)
        Doc -> Doc -> Doc
<+> Doc -> (ClassExpression -> Doc) -> Maybe ClassExpression -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Doc
keyword "Thing") ClassExpression -> Doc
printPrimary Maybe ClassExpression
maybeDesc
   AS.DataValuesFrom ty :: QuantifierType
ty dpExp :: [IRI]
dpExp dRange :: DataRange
dRange ->
       IRI -> Doc
printIRI ([IRI] -> IRI
forall a. [a] -> a
head [IRI]
dpExp) Doc -> Doc -> Doc
<+> QuantifierType -> Doc
quantifierType QuantifierType
ty
        Doc -> Doc -> Doc
<+> DataRange -> Doc
forall a. Pretty a => a -> Doc
pretty DataRange
dRange
   AS.DataHasValue dpExp :: IRI
dpExp cons :: Literal
cons -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
dpExp Doc -> Doc -> Doc
<+> String -> Doc
keyword String
valueS Doc -> Doc -> Doc
<+> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
cons
   AS.DataCardinality (AS.Cardinality ty :: CardinalityType
ty card :: Int
card dpExp :: IRI
dpExp maybeRange :: Maybe DataRange
maybeRange) ->
       IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
dpExp Doc -> Doc -> Doc
<+> CardinalityType -> Doc
cardinalityType CardinalityType
ty Doc -> Doc -> Doc
<+> String -> Doc
text (Int -> String
forall a. Show a => a -> String
show Int
card)
         Doc -> Doc -> Doc
<+> Doc -> (DataRange -> Doc) -> Maybe DataRange -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc
empty DataRange -> Doc
forall a. Pretty a => a -> Doc
pretty Maybe DataRange
maybeRange

printPrimary :: AS.ClassExpression -> Doc
printPrimary :: ClassExpression -> Doc
printPrimary d :: ClassExpression
d = let dd :: Doc
dd = ClassExpression -> Doc
forall a. Pretty a => a -> Doc
pretty ClassExpression
d in case ClassExpression
d of
  AS.ObjectJunction {} -> Doc -> Doc
parens Doc
dd
  _ -> Doc
dd

printNegatedPrimary :: AS.ClassExpression -> Doc
printNegatedPrimary :: ClassExpression -> Doc
printNegatedPrimary d :: ClassExpression
d = let r :: Doc
r = Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ ClassExpression -> Doc
forall a. Pretty a => a -> Doc
pretty ClassExpression
d in case ClassExpression
d of
  AS.ObjectComplementOf _ -> Doc
r
  AS.ObjectValuesFrom {} -> Doc
r
  AS.DataValuesFrom {} -> Doc
r
  AS.ObjectHasValue {} -> Doc
r
  AS.DataHasValue {} -> Doc
r
  _ -> ClassExpression -> Doc
printPrimary ClassExpression
d

-- | annotations printing
instance Pretty AS.AnnotationValue where
    pretty :: AnnotationValue -> Doc
pretty x :: AnnotationValue
x = case AnnotationValue
x of
        AS.AnnAnInd i :: IRI
i -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
i
        AS.AnnValue iri :: IRI
iri -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
iri
        AS.AnnValLit lit :: Literal
lit -> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
lit

instance Pretty AS.Annotation where
    pretty :: Annotation -> Doc
pretty = Annotation -> Doc
printAnnotation

printAnnotation :: AS.Annotation -> Doc
printAnnotation :: Annotation -> Doc
printAnnotation (AS.Annotation ans :: [Annotation]
ans ap :: IRI
ap av :: AnnotationValue
av) =
    [Doc] -> Doc
sep [[Annotation] -> Doc
printAnnotations [Annotation]
ans, [Doc] -> Doc
sep [IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
ap, AnnotationValue -> Doc
forall a. Pretty a => a -> Doc
pretty AnnotationValue
av]]

printAnnotations :: Annotations -> Doc
printAnnotations :: [Annotation] -> Doc
printAnnotations l :: [Annotation]
l = case [Annotation]
l of
    [] -> Doc
empty
    _ -> String -> Doc
keyword String
annotationsC Doc -> Doc -> Doc
<+>
          [Doc] -> Doc
vcat (Doc -> [Doc] -> [Doc]
punctuate Doc
comma ((Annotation -> Doc) -> [Annotation] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ (AS.Annotation ans :: [Annotation]
ans ap :: IRI
ap av :: AnnotationValue
av) ->
            [Annotation] -> Doc
printAnnotations [Annotation]
ans Doc -> Doc -> Doc
$+$ Annotation -> Doc
forall a. Pretty a => a -> Doc
pretty ([Annotation] -> IRI -> AnnotationValue -> Annotation
AS.Annotation [] IRI
ap AnnotationValue
av)) [Annotation]
l) )

printAnnotatedList :: Pretty a => AnnotatedList a -> Doc
printAnnotatedList :: AnnotatedList a -> Doc
printAnnotatedList l :: AnnotatedList a
l =
    [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
punctuate Doc
comma ([Doc] -> [Doc]) -> [Doc] -> [Doc]
forall a b. (a -> b) -> a -> b
$ (([Annotation], a) -> Doc) -> AnnotatedList a -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map
        ( \ (ans :: [Annotation]
ans, a :: a
a) -> [Annotation] -> Doc
printAnnotations [Annotation]
ans Doc -> Doc -> Doc
$+$ a -> Doc
forall a. Pretty a => a -> Doc
pretty a
a) AnnotatedList a
l