Эта функция генерирует простые файлы .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
.
Проблема в том, что formatGraph
сохраняет двойные кавычки вокруг строк, что приводит к ошибкам в Graphviz. Например, когда я печатаю unlines $ prepGraph
в файл, я получаю такие вещи:
0 -> 1 [ label = "('a', "N. SF")" ];
вместо
0 -> 1 [ label = "('a', N. SF)" ];
(Тем не менее, "Null", кажется, работает нормально, и выводит отлично). Теперь, конечно, строка «N. SF» не является реальной формой, которую я использую для хранения перегибов, но эта форма содержит строку или два. Итак, как я могу сказать Haskell: когда вы show
значения String, не ставьте его в двойные кавычки?