ppFlatTermF :: Applicative f => (Prec -> t -> f Doc) -> Prec -> FlatTermF t -> f Doc
ppFlatTermF pp prec tf =
  case tf of
    GlobalDef i -> pure $ ppIdent i
    UnitValue     -> pure $ text "()"
    UnitType      -> pure $ text "#()"
    PairValue x y -> ppParens (prec > PrecApp) <$>
                       (infixDoc "#" <$> pp PrecApp x <*> pp PrecApp y)
    PairType x y  -> ppParens (prec > PrecApp) <$>
                       (infixDoc "*" <$> pp PrecApp x <*> pp PrecApp y)
    PairLeft t    -> ppParens (prec > PrecArg) . (<> (text ".L")) <$> pp PrecArg t
    PairRight t   -> ppParens (prec > PrecArg) . (<> (text ".R")) <$> pp PrecArg t
{-
    TupleValue l ->                 tupled <$> traverse (pp PrecNone) l
    TupleType l  -> (char '#' <>) . tupled <$> traverse (pp PrecNone) l
    TupleSelector t i -> ppParens (prec > PrecArg)
                           . (<> (char '.' <> int i)) <$> pp PrecArg t
-}

    RecordValue m      -> ppRecordF (pp PrecNone) m
    RecordType m       -> (char '#' <>) <$> ppRecordF (pp PrecNone) m
    RecordSelector t f -> ppParens (prec > PrecArg)
                          . (<> (char '.' <> text f)) <$> pp PrecArg t

    CtorApp c l      -> ppAppList prec (ppIdent c) <$> traverse (pp PrecArg) l
    DataTypeApp dt l -> ppAppList prec (ppIdent dt) <$> traverse (pp PrecArg) l

    Sort s -> pure $ text (show s)
    NatLit i -> pure $ integer i
    ArrayValue _ vl -> list <$> traverse (pp PrecNone) (V.toList vl)
    FloatLit v  -> pure $ text (show v)
    DoubleLit v -> pure $ text (show v)
    StringLit s -> pure $ text (show s)
    ExtCns (EC _ v _) -> pure $ text v
ppFlatTermF :: Applicative f => (Prec -> t -> f Doc) -> Prec -> FlatTermF t -> f Doc
ppFlatTermF pp prec tf =
  case tf of
    GlobalDef i -> pure $ ppIdent i
    UnitValue     -> pure $ text "()"
    UnitType      -> pure $ text "#()"
    PairValue x y -> ppParens (prec > PrecApp) <$>
                       (infixDoc "#" <$> pp PrecApp x <*> pp PrecApp y)
    PairType x y  -> ppParens (prec > PrecApp) <$>
                       (infixDoc "*" <$> pp PrecApp x <*> pp PrecApp y)
    PairLeft t    -> ppParens (prec > PrecArg) . (<> (text ".L")) <$> pp PrecArg t
    PairRight t   -> ppParens (prec > PrecArg) . (<> (text ".R")) <$> pp PrecArg t
{-
    TupleValue l ->                 tupled <$> traverse (pp PrecNone) l
    TupleType l  -> (char '#' <>) . tupled <$> traverse (pp PrecNone) l
    TupleSelector t i -> ppParens (prec > PrecArg)
                           . (<> (char '.' <> int i)) <$> pp PrecArg t
-}

    RecordValue m      -> ppRecordF (pp PrecNone) m
    RecordType m       -> (char '#' <>) <$> ppRecordF (pp PrecNone) m
    RecordSelector t f -> ppParens (prec > PrecArg)
                          . (<> (char '.' <> text f)) <$> pp PrecArg t

    CtorApp c l      -> ppAppList prec (ppIdent c) <$> traverse (pp PrecArg) l
    DataTypeApp dt l -> ppAppList prec (ppIdent dt) <$> traverse (pp PrecArg) l

    Sort s -> pure $ text (show s)
    NatLit i -> pure $ integer i
    ArrayValue _ vl -> list <$> traverse (pp PrecNone) (V.toList vl)
    FloatLit v  -> pure $ text (show v)
    DoubleLit v -> pure $ text (show v)
    StringLit s -> pure $ text (show s)
    ExtCns (EC _ v _) -> pure $ text v
ppFlatTermF pp prec tf =
  case tf of
    GlobalDef i -> pure $ ppIdent i
    UnitValue     -> pure $ text "()"
    UnitType      -> pure $ text "#()"
    PairValue x y -> ppParens (prec > PrecApp) <$>
                       (infixDoc "#" <$> pp PrecApp x <*> pp PrecApp y)
    PairType x y  -> ppParens (prec > PrecApp) <$>
                       (infixDoc "*" <$> pp PrecApp x <*> pp PrecApp y)
    PairLeft t    -> ppParens (prec > PrecArg) . (<> (text ".L")) <$> pp PrecArg t
    PairRight t   -> ppParens (prec > PrecArg) . (<> (text ".R")) <$> pp PrecArg t
{-
    TupleValue l ->                 tupled <$> traverse (pp PrecNone) l
    TupleType l  -> (char '#' <>) . tupled <$> traverse (pp PrecNone) l
    TupleSelector t i -> ppParens (prec > PrecArg)
                           . (<> (char '.' <> int i)) <$> pp PrecArg t
-}

    RecordValue m      -> ppRecordF (pp PrecNone) m
    RecordType m       -> (char '#' <>) <$> ppRecordF (pp PrecNone) m
    RecordSelector t f -> ppParens (prec > PrecArg)
                          . (<> (char '.' <> text f)) <$> pp PrecArg t

    CtorApp c l      -> ppAppList prec (ppIdent c) <$> traverse (pp PrecArg) l
    DataTypeApp dt l -> ppAppList prec (ppIdent dt) <$> traverse (pp PrecArg) l

    Sort s -> pure $ text (show s)
    NatLit i -> pure $ integer i
    ArrayValue _ vl -> list <$> traverse (pp PrecNone) (V.toList vl)
    FloatLit v  -> pure $ text (show v)
    DoubleLit v -> pure $ text (show v)
    StringLit s -> pure $ text (show s)
    ExtCns (EC _ v _) -> pure $ text v