Haskell: 漂亮的打印中缀和前缀
Haskell: Pretty print infix and prefix
我有一个类型来表示 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 附带 pretty
and I also recommend the newer prettyprinter
.
使用前者(并假设 type Name = String
):
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)
我有一个类型来表示 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 附带 pretty
and I also recommend the newer prettyprinter
.
使用前者(并假设 type Name = String
):
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)