[英]Removing String double-quotes in Haskell
此函数生成简单的.dot文件,以使用Graphviz可视化自动机转换函数。 它的主要目的是调试大量自动生成的转换(例如,拉丁语动词的变形)。
prepGraph :: ( ... ) => NFA c b a -> [String]
prepGraph nfa = "digraph finite_state_machine {"
: wrapSp "rankdir = LR"
: wrapSp ("node [shape = circle]" ++ (mapSp (states nfa \\ terminal nfa)))
: wrapSp ("node [shape = doublecircle]" ++ (mapSp $ terminal nfa))
: formatGraph nfa ++ ["}"]
formatGraph :: ( ... ) => NFA c b a -> [String]
formatGraph = map formatDelta . deltaTuples
where formatDelta (a, a', bc) = wrapSp (mkArrow a a' ++ " " ++ mkLabel bc)
mkArrow x y = show x ++ " -> " ++ show y
mkLabel (y, z) = case z of
(Just t) -> "[ label = \"(" ++ show y ++ ", " ++ show t ++ ")\" ]"
Nothing -> "[ label = \"(" ++ show y ++ ", " ++ "Null" ++ ")\" ]"
其中wrap
, wrapSp
和mapSp
是格式化函数, deltaTuples
也是deltaTuples
。
问题是formatGraph
在字符串周围保留双引号,这会导致Graphviz中的错误。 例如,当我unlines $ prepGraph
打印成文件时,我得到的结果如下:
0 -> 1 [ label = "('a', "N. SF")" ];
代替
0 -> 1 [ label = "('a', N. SF)" ];
(但是,“Null”似乎工作正常,并且输出非常好)。 当然,字符串“N.SF”不是我用来存储变形的实际形式,但是该形式确实包含一个或两个String。 那么我怎么能告诉Haskell:当你show
一个String值时,不要双引号呢?
看看Martin Erwig如何在Data.Graph.Inductive.Graphviz中处理同样的问题:
您正在寻找的功能是底部的“sq”:
sq :: String -> String
sq s@[c] = s
sq ('"':s) | last s == '"' = init s
| otherwise = s
sq ('\'':s) | last s == '\'' = init s
| otherwise = s
sq s = s
(检查上下文并适应您自己的代码,当然)
使用dotgen包 - 它具有特殊的保护措施,以防止禁止的字符潜入属性值。
您可以像这样定义自己的typeClass:
class GShow a where
gShow :: a -> String
gShow = show
instance GShow String where
show = id
instance GShow Integer
instance GShow Char
-- And so on for all the types you need.
“gShow”的默认实现是“show”,因此每个实例都不需要“where”子句。 但是你确实需要所有的实例,这有点拖累。
或者,您可以使用重叠实例 。 我认为(虽然我没有尝试过),这将允许您使用默认的“gShow”替换单行的实例列表:
instance (Show a) => GShow a
我们的想法是,对于重叠的实例,编译器将选择最具体的实例。 因此对于字符串,它将在更一般的字符串上选择字符串实例,而对于其他所有字符串实例,通用字符串实例是唯一匹配的字符串实例
它似乎有点难看,但你可以应用filter
来show t
filter (/='"') (show t)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.