2016-03-25 4 views
0

私は今作成して印刷しようとしているこれらのデータ型を定義しました。Haskell - 正しい出力を得るためにショーを変更する方法

["A","B"]   -- [TNonTerminal] 
"abc"    -- [TTerminals] 
"A"    -- TNonTerminal 
["A"->["aaB"]  -- 
,"A"->["ccB"] 
,"B"->["bB"]  -- [Rule] 
,"B"->["#"] 
]     -- 

がどのように変更する必要があります(私はタイプRightLinearGrammarを作成し、putStr $ show rlgと呼ば明確化のために)

type TNonTerminal = String -- will be creating own ones where [A-Z] won't be enough 
type TTerminals = Char 
type TSymbols = String -- both terminals and nonterminals 

data Rule = Rule 
    { leftSide :: TNonTerminal 
    , rightSide :: [TSymbols] 
    } deriving (Eq) 

data RightLinearGrammar = RLG 
    { nonterminals :: [TNonTerminal] 
    , terminals :: [TTerminals] 
    , firstNonterminal :: TNonTerminal 
    , rules :: [Rule] 
    } deriving (Eq) 

は、だから私はまた、これらの表示インスタンス

instance Show Rule where 
    show (Rule ls rs) = show ls ++ "->" ++ show rs ++ "\n" 

instance Show RightLinearGrammar where 
    show (RLG n t fn r) = show n ++ "\n" ++ show t ++ "\n" ++ show fn ++ "\n" ++ show r ++ "\n" 

を作成し、私はこの出力を取得しますこのようなより良い出力を得るためのコードですか?

A,B 
a,b,c 
A 
A->aaB 
A->ccB 
B->bB 
B-># 

答えて

1

showあなたのリストの周りの文字列と括弧の前後に引用符を与えるつもりはデフォルトです。あなただけ戻って文字列を連結し、コンマまたは改行でリストに参加するに行く場合は、あなたが期待している出力を取得する必要があります:

import Data.List (intercalate) 

instance Show Rule where 
    show (Rule ls rs) = ls ++ "->" ++ intercalate "," rs 

instance Show RightLinearGrammar where 
    show (RLG n t fn r) = intercalate "," n ++ "\n" ++ t ++ "\n" ++ fn ++ "\n" ++ (intercalate "\n" $ map show r) ++ "\n" 
+0

というように書き直すことを検討してください。 intersperseやconcatのような機能が存在することは知らなかった。 – Dracke

+1

私は 'intercalate'を使うように更新しました。これは' concat $ intersperse xs xss'の省略形です。 –

1

次のいずれかnewtypesであなたのタイプの同義語を交換し、にそれらにshowを定義する必要があります必要な機能を実行するか、インスタンス内のshowへの呼び出しをカスタムフォーマッタ機能の呼び出しで置き換える可能性が高くなります。

注:は通常、ghciに貼り付けられた出力を生成するため、あなたがしようとしているものには適切な機能ではなく、間違いなくその使用に制限する必要があります。

formatRule :: Rule -> String 
formatRule (Rule ls rs) = ls ++ "->" ++ concat (intersperse "," rs) ++ "\n" 

formatRightLinearGrammar :: RightLinearGrammar -> String 
formatRightLinearGrammar (RLG n t fn r) = 
     concat (intersperse "," n) ++ "\n" 
    ++ intersperse ',' t ++ "\n" 
    ++ fn ++ "\n" 
    ++ concat (map formatRule r) 

注:これは大きな文法ではかなり効率が悪くなります。

formatRule :: Rule -> String -> String 
formatRule (Rule ls rs) = (ls++) . ("->"++) . concatDS (intersperse "," rs) . ("\n"++) 

formatRightLinearGrammar :: RightLinearGrammar -> String 
formatRightLinearGrammar (RLG n t fn r) = 
    concatDS (intersperse "," n) $ ("\n"++) $ 
    (intersperse ',' t ++) $ ("\n"++) $ 
    (fn++) $ ("\n"++) $ 
    foldr formatRule "" r 

concatDS ss s' = foldr (++) s' ss 
関連する問題