Chris Mears | 29 Jan 00:38 2013
Picon

Uniplate and rewriting with different types

Hi all,

I have a question about the Uniplate library, regarding rewriting with
transformations that have different types.

With the following type, and transformation functions:

    data Odd = OddOne Even | OddZero Even          deriving (Data,Typeable,Show)
    data Even = EvenOne Odd | EvenZero Odd | Nil   deriving (Data,Typeable,Show)

    t1,t2,t3 :: Even -> Maybe Even

    t1 (EvenOne (OddOne x)) = Just $ EvenOne (OddZero x)
    t1 x                    = Nothing

    t2 (EvenOne (OddZero x)) = Just $ EvenZero (OddOne x)
    t2 x                     = Nothing

    t3 (EvenZero (OddOne x)) = Just $ EvenZero (OddZero x)
    t3 x                     = Nothing

it is easy to combine the transformations into a single
transformation, because they all have the same type.  The result can
then be passed to the Uniplate's "rewriteBi" function:

    allts x = t1 x `mplus` t2 x `mplus` t3 x
    example = OddOne (EvenOne (OddOne (EvenOne (OddOne Nil))))
    go = rewriteBi allts example

But if one of the transformations has a different type, you can't do
(Continue reading)

Neil Mitchell | 29 Jan 22:00 2013
Picon

Re: Uniplate and rewriting with different types

Hi Chris,

> With the following type, and transformation functions:
>
>     data Odd = OddOne Even | OddZero Even          deriving (Data,Typeable,Show)
>     data Even = EvenOne Odd | EvenZero Odd | Nil   deriving (Data,Typeable,Show)
>
>     t1,t2,t3 :: Even -> Maybe Even

> But if one of the transformations has a different type, you can't do
> it this way.  For instance, redefine t2 to have a different type:
>
>     t2 :: Odd -> Maybe Odd
>     t2 (OddZero (EvenOne x)) = Just $ OddZero (EvenZero x)
>     t2 x                     = Nothing
>
> and you are stuck because the functions of different types can't be
> combined into a single transformation.
>
> My question is: is there a good way to combine the transformation
> functions if they have different types?

Currently, no. Although there is something definitely related, with
transformBis: http://hackage.haskell.org/packages/archive/uniplate/1.6.10/doc/html/Data-Generics-Uniplate-Data.html#v:transformBis

That takes a list of transformation functions of different types and
acts as though you did transform on each one in turn. You could
certainly imagine adding rewriteBis in the same style, and with your
version you almost have. The transformBis function is particularly
efficient because it "knows" which traversals or parts of traversals
(Continue reading)


Gmane