dato, per esempio, il seguente tipo di dati ad albero:Poiché "fold" non è abbastanza potente per scrivere un albero abbastanza-stampante con indentazione, quale combinatore di ordine elevato è?
data Tree a = Node [Tree a] | Leaf a deriving Show
type Sexp = Tree String
Come si esprimo una funzione di "bella" con un combinatore di ordine superiore, che stampa l'albero con una corretta indentazione? Per esempio:
sexp =
Node [
Leaf "aaa",
Leaf "bbb",
Node [
Leaf "ccc",
Leaf "ddd",
Node [
Leaf "eee",
Leaf "fff"],
Leaf "ggg",
Leaf "hhh"],
Leaf "jjj",
Leaf "kkk"]
pretty = ????
main = print $ pretty sexp
Voglio che il risultato di tale programma sia:
(aaa
bbb
(ccc
ddd
(eee
fff)
ggg
hhh)
jjj
kkk)
Qui è una soluzione incompleta, utilizzando una "piega", come il combinatore, che non implementa l'indentazione:
fold f g (Node children) = f (map (fold f g) children)
fold f g (Leaf terminal) = g terminal
pretty = fold (\ x -> "(" ++ (foldr1 ((++) . (++ " ")) x) ++ ")") show
main = putStrLn $ pretty sexp
non è ovviamente possibile scrivere la funzione che voglio utilizzare fold
, dal momento che dimentica la struttura ad albero. Quindi, qual è un corretto combinatore di alto ordine che è abbastanza generico da permettermi di scrivere la funzione che voglio, ma meno potente della scrittura di una funzione ricorsiva diretta?
Non so, qualcosa con monadi? – bb94
Immagino che le monadi siano troppo potenti per quello che voglio. Ovviamente questo è fattibile con loro, ma immagino che qualcosa di meno generico possa ancora farcela. Qualcosa sulle pieghe con contesto ... non ne sono sicuro. – MaiaVictor
Questo suona sicuramente come le monadi! – bb94