2017-09-11 4 views
2

私は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 = ??? 

どのように私はこれを実装することができますか?

+1

あなたはちょうど私が理解し、あなた自身の啓発のためにこれをやっている場合は、それ以外の私は[Haskellの-SRC-EXTS](httpsにあなたを指すようになります/ /hackage.haskell.org/package/haskell-src-exts-1.19.1/docs/Language-Haskell-Exts-Pretty.html)には、かなりのプリンタとHaskellコード用の正確なプリンタがあります。 –

答えて

3

これを行う通常の方法は、印刷機能の優先順位変数を設定することです。また、ほとんどの場合、生の文字列を使用するのではなく、パフォーマンス上の理由から、簡単にライブラリを使うほうがいいでしょう。 GHCはprettyに同梱されており、さらに新しい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)