функции, которые примерно то, что вы пытались написать сами.

я проблемы с добавлением экземпляра show в мою структуру данных, которая:

data Structure = Structure String [Structure]  

и я хотел бы получить этот вывод:

strct  
    strct1  
    strct2  
    strct3  

Я пытался это

instance Show Structure where  
    show (Structure a (xs)) = show a ++ "\n" ++ "  " ++ show xs  

Но его вывод

"strct"  
    ["strct1"  
    [], "strct2"  
    []]  

Поэтому мне не нужны ни скобки, ни запятые, ни кавычки. Есть идеи? Спасибо

 Jason Hu18 нояб. 2017 г., 21:17
так что я думаю, что каждая структура должна иметь более глубокий отступ на один уровень?
 Peter Martins18 нояб. 2017 г., 21:19
Я бы не стал! Тем не менее, мой учитель сказал мне, что мне нужно кодировать это таким образом ... @ReinHenrichs
 Peter Martins18 нояб. 2017 г., 21:22
Точно @HuStmpHrrr
 Rein Henrichs18 нояб. 2017 г., 21:16
Вы не должны использоватьShow для красивой печати. Доступны красивые библиотеки печати, которые значительно облегчат вам эту задачу.

Ответы на вопрос(3)

есть только одна бухгалтерия, то есть сохранить уровень отступа. Накопительный счетчик определенно помогает:

pretty' :: Int -> Structure -> [String]
pretty' level (Structure s list) = ((concat $ replicate level "    ") ++ s) :
    (list >>= (pretty' (level + 1)))

Эта функция определяет аккумулятор вашего симпатичного принтера. Оставшаяся часть должна обернуть это:

pretty = pretty' 0
prettyShow = unlines . pretty

Это определенно работает

Prelude> putStrLn $ prettyShow (Structure "a" [Structure "b" [Structure "c" []], Structure "d" []])
a
    b
        c
    d
 Jason Hu18 нояб. 2017 г., 22:19
Я только что понял, что часть моего обсуждения катаморфизма неверна, поэтому я удалил ее. рекурсия должна быть разнородной. но оставшаяся часть работает и должно быть достаточно, чтобы ответить на вопрос ОП.

Я бы предложил использоватьData.Tree модуль, который поставляется сbase, Это общее (розовое) дерево со структурой, идентичной вашей, за исключением того, что список идет по синониму типа:

data Tree a = Node {rootLabel :: a, subForest :: Forest a}
type Forest a = [Tree a]

Это также идет сdrawTree а такжеdrawForest функции, которые примерно то, что вы пытались написать сами.

> :m + Data.Tree
> let t = Node "strct" [Node "strct1" [], Node "strct2" [], Node "strct3" []]
> putStr . drawTree $ t
strct
|
+- strct1
|
+- strct2
|
`- strct3
Решение Вопроса

что для этого есть лучшие библиотечные процедуры, но разве это не сработает?

unlines $ a : ["  " ++ show x | x <- xs]

Тем не менее, это охватывает только один уровень. Возможно, вы захотите определить функцию, отличную от show, чтобы сохранить отступ, или вам придется продолжать разделять суб-шоу с помощьюlines чтобы найти, где ввести отступ.

Черновой вариант такой функции вставки отступа:

prefix p s = unlines [p ++ l | l <- lines s]

Опять же, я уверен, что в библиотеке что-то лучше. Даже эти короткие фрагменты прошли несколько этапов уточнения (foldl1 (++) ->concat ->unlinesзатем присоединитесь к первой строке:).

 Adam Smith18 нояб. 2017 г., 23:01
@YannVernier обратите внимание, чтоunlines не * по существуconcatMap (++"\n"), этоименно так это. Изисточник: unlines = concatMap (++ "\n")
 Yann Vernier18 нояб. 2017 г., 21:51
Вторая мысль:unlines по существуconcatMap (++"\n"), Что в прошлом\n может быть пропущен сfoldl1 (\a b -> a++"\n"++b), Что, конечно, было бы более разборчивым, какintercalate "\n".
 Yann Vernier18 нояб. 2017 г., 21:37
Первая (глупая) мысль: отрезать последнего персонажа, используяinit?
 Peter Martins18 нояб. 2017 г., 21:30
Это работает, спасибо! Тем не менее, он добавляет новую строку в конце каждой структуры. У вас есть идея, как я могу это исправить?
 Yann Vernier19 нояб. 2017 г., 08:44
По крайней мере, был ifdef с альтернативной версией. ;) Честно говоря, стандартная библиотека для хранения кода, который вы можете написать, является сильной стороной Haskell; это означает, что компилятор преуспеет со многими вещами, которые мы придумаем.

Ваш ответ на вопрос