Haskell-如何更改节目以获得正确的输出

Haskell-如何更改节目以获得正确的输出,haskell,Haskell,我已经定义了这些数据类型,我正在尝试创建和打印这些数据类型 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 ,

我已经定义了这些数据类型,我正在尝试创建和打印这些数据类型

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"
我得到了这个输出(为了澄清,我创建了rightlineargramar类型,并调用了
putStr$show rlg
):

我应该如何更改代码以获得更好的输出

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

默认情况下,
show
在字符串周围加引号,在列表周围加括号。如果您只是返回到用逗号或换行符连接字符串和列表,您应该会得到预期的输出:

导入数据列表(插入)
实例显示规则在哪里
显示(规则ls rs)=ls++“->”+++插入“,”rs
实例Show rightlineargramar,其中
show(RLG n t fn r)=插入“,”n++“\n“++t++”\n“++fn++”\n“++”(插入“\n”$map show r)++”\n”

您或者需要将类型同义词替换为
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

这很有效。我不知道像intersperse和concat这样的函数存在。我只是更新了它,使用了
interlate
,这是
concat$intersperse xss
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