我已定义了这些数据类型,我正在尝试创建并立即打印。
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)
所以我也创建了那些Show实例
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"
我得到了这个输出(为了澄清我创建了Type RightLinearGrammar并调用了putStr $ show rlg
):
["A","B"] -- [TNonTerminal]
"abc" -- [TTerminals]
"A" -- TNonTerminal
["A"->["aaB"] --
,"A"->["ccB"]
,"B"->["bB"] -- [Rule]
,"B"->["#"]
] --
如何更改代码以获得更好的输出?
A,B
a,b,c
A
A->aaB
A->ccB
B->bB
B->#
答案 0 :(得分: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"
答案 1 :(得分:1)
您需要使用newtypes
替换类型同义词,并在其上定义show
以执行您想要的操作,或者更有可能通过调用替换您实例中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