2010-03-11 5 views
0

J'utilise uniplaque et SYB et je suis en train de transformer une listerépertorie les recherches dans SYB ou uniplaque haskell

Par exemple

type Tree = [DataA] 

data DataA = DataA1 [DataB] 
      | DataA2 String 
      | DataA3 String [DataA] 
       deriving Show 

data DataB = DataB1 [DataA] 
      | DataB2 String 
      | DataB3 String [DataB] 
       deriving Show 

Par exemple, je voudrais parcourir mon arbre et ajouter une valeur à tous [Datab]

ma première pensée était de le faire:

changeDataB:: Tree -> Tree 
changeDataB = everywhere(mkT changeDataB') 
chanegDataB'::[DataB] -> [DataB] 
changeDataB' <add changes here> 

ou si j'utilise uniplate

changeDataB:: Tree -> Tree 
    changeDataB = transformBi changeDataB' 
    chanegDataB'::[DataB] -> [DataB] 
    changeDataB' <add changes here> 

Le problème est que je veux seulement chercher sur la liste complète. L'une de ces recherches entraînera une recherche sur la liste complète et toutes les sous-listes (y compris la liste vide)

L'autre problème est qu'une valeur dans [DataB] peut générer un [DataB], donc Je ne sais pas si c'est le même genre de solution que de ne pas chercher de caractères dans une chaîne.

Je pourrais correspondre à un modèle sur DataA1 et DataB3, mais dans mon application réelle, il y a un tas de [DataB]. La correspondance des motifs avec les parents serait étendue.

L'autre pensée que je devais était de créer un

data DataBs = [DataB] 

et l'utiliser pour transformer le. Cela semble un peu boiteux, il doit y avoir une meilleure solution.

Mise à jour: La principale raison pour laquelle je dois faire ce que je dois

  1. changer l'ordre de [Datab]
  2. ajouter quelque chose à [Datab]

Alors si vous connaissez tous un moyen cool de créer un mkT qui correspondrait

B1: B2: B3: B4: [] (ce qui serait par exemple la liste complète de [DataB]

et non

B2: B3: B4: []
ou tout autre dérivations de cela.

Je suis juste en train de mordre la balle et de créer le type de données "DataBs" et de faire une simple correspondance mkT là-dessus.

+0

Quelle est exactement la "liste complète" dont vous parlez? Pourriez-vous fournir des exemples de certaines "listes complètes" avant et après la transformation souhaitée? – ADEpt

+0

Disons que je voulais remplacer toutes les chaînes avec "foo". Faire un transformBi strToFoo strToFoo :: String -> Chaîne strToFoo x = "toto" ne fonctionnerait pas parce que String = [Char] permet donc dire que x = DataA2 "salut" Cela signifie réellement x = DataA2 h: i: [] je recevrais matchs sur h: i: [] i: [] et [] Ainsi, le résultat de ma transformation serait x = Foo: Foo: Foo : Foo (ou quelque chose comme ça) Je viens de mordre le b ullet et créé ma fonction de transformation qui le résout. Plus je pense à cela, je ne pense pas qu'il y a une façon simple de le faire sans regarder le parent Constructeur. – Chris

Répondre

1

Je liquidée créer ma propre fonction de transformation

Alors

dataBListTrans:: ([DataB] -> [DataB]) -> Tree -> Tree 
dataBListTrans f = transformBi $ dataAs f . (transformBi $ dataBs f) 
where 
    dataAs f (DataA1 a bs) = DataA1 a (f bs) 
    dataAs x = x 
    dataBs f (DataB3 s bs) = DataB3 s (f bs) 
    dataBs x = x 

Il est une sorte de douleur pour créer une structure de données plus grande, mais cela a été le meilleur que je pouvais venir avec

Questions connexes