Haskell:漂亮的打印中缀和前缀

Haskell:漂亮的打印中缀和前缀,haskell,types,abstract-syntax-tree,pretty-print,Haskell,Types,Abstract Syntax Tree,Pretty Print,我有一个类型来表示haskell类型: data Type = TApp Type Type | TVar Name | TLit Name infixl 8 `TApp` -- a -> b aToB = TLit "Fun" `TApp` TVar "a" `TApp` TVar "b" -- Maybe (IO Int) maybeIOInt = TLit "Maybe" `TApp` (TLit "IO" `TApp` TLit "Int") 我想像

我有一个类型来表示haskell类型:

data Type 
    = TApp Type Type
    | TVar Name
    | TLit Name
infixl 8 `TApp`

-- a -> b
aToB = TLit "Fun" `TApp` TVar "a" `TApp` TVar "b"

-- Maybe (IO Int)
maybeIOInt = TLit "Maybe" `TApp` (TLit "IO" `TApp` TLit "Int")
我想像haskell那样打印它,也就是说,作为符号的文字是中缀打印的,而其他文字是前缀打印的。 必要时还应添加括号:

show aToB = "a -> b"
show maybeIOInt = "Maybe (IO Int)"

show ast = ???

如何实现这一点?

通常的方法是通过线程将优先变量传递给打印函数。此外,您几乎总是应该喜欢一个漂亮的打印库,而不是仅仅使用原始字符串(出于性能原因和方便起见)。GHC随附,我也推荐更新的

使用前者(并假设
type Name=String
):

import Text.PrettyPrint.HughesPJ
prettyType::类型->单据
prettyType=go 0
哪里
go::Int->Type->Doc
go(TVar x)=文本x
go uIt(TLit n)=文本n
go n(t“Fun”`TApp`l`TApp`r)=可能是对的(n>0)(go 1l文本“->”go 0r)
go n(l`TApp`r)=可能是对立面(n>1)(go 1 l go 2 r)

如果您这样做只是为了自己的启发,我理解,否则我会向您指出,它有一台漂亮的打印机和一台精确的Haskell代码打印机。
import Text.PrettyPrint.HughesPJ

prettyType :: Type -> Doc
prettyType = go 0
  where
    go :: Int -> Type -> Doc
    go _ (TVar x) = text x
    go _ (TLit n) = text n
    go n (TLit "Fun" `TApp` l `TApp` r) = maybeParens (n > 0) (go 1 l <+> text "->" <+> go 0 r)
    go n (l `TApp` r) = maybeParens (n > 1) (go 1 l <+> go 2 r)