0

I have been using uniplate and SYB and I am trying to transform a list

For instance

    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

For instance, I would like to traverse my tree and append a value to all [DataB]

So my first thought was to do this:

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

or if I was using uniplate

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

The problem is that I only want to search on the full list. Doing either of these searches will cause a search on the full list and all of the sub-lists (including the empty list)

The other problem is that a value in [DataB] may generate a [DataB], so I don't know if this is the same kind of solution as not searching chars in a string.

I could pattern match on DataA1 and DataB3, but in my real application there are a bunch of [DataB]. Pattern matching on the parents would be extensive.

The other thought that I had was to create a

data DataBs = [DataB]

and use that to transform on. That seems kind of lame, there must be a better solution.

Update: The main reason that I need to do this is that I need to

  1. change the order of [DataB]
  2. add something to [DataB]

So if you all know a cool way to create a mkT that would match

B1:B2:B3:B4:[] (which would be per say the full list of [DataB]

and not

B2:B3:B4:[]
or any other derivations of that.

I am siding to just biting the bullet and createing the "DataBs", data type and doing a simple mkT match on that.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
Chris
  • 483
  • 3
  • 14
  • What exactly is the "full list" you are speaking about? Could you provide samples of some "full lists" before and after the desired transformation? – ADEpt Mar 12 '10 at 11:59
  • Lets say that I wanted to replace all Strings with "foo". Doing a transformBi strToFoo strToFoo:: String -> String strToFoo x = "foo" Would not work because String = [Char] So lets say that x = DataA2 "hi" That actually means x = DataA2 h:i:[] I would get matches on h:i:[] i:[] and [] So the result of my transform would be x = Foo:Foo:Foo:Foo (or something like that) I just bit the bullet and created my on transformation function which solves it. The more that I think of it, I dont think that there is a slick way of doing this without looking at the parent Constructor. – Chris Mar 12 '10 at 20:17

1 Answers1

1

I wound up creating my own transformation function

So

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

It is kind of a pain to create for a larger data structure, but this was the best that I could come up with

Chris
  • 483
  • 3
  • 14