Examples for Control.Lens.Plated?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Examples for Control.Lens.Plated?

Andrey Chudnov
Hello Cafe,
I'm considering porting some of my code that uses uniplate to lens. But
Control.Lens.Plated is giving me headaches. So I'm looking for remedy.

Has anyone used it and willing to share examples? I hope that seeing
some of the combinators in action would help me understand the type
signatures and documentation. What I'm particularly interested in is the
following:
1) implementation of something like transformBi and rewriteBi using lens
2) usage of *On, *Off and *OnOff combinators (e.g., transformMOn,
transformMOff, transformMOnOff). What I want to understand is the
difference between the 3 variants. Also, what does it mean to "Transform
every element in the tree in a region indicated by a supplied Traversal"
and how exactly does the traversal define the region.
3) any recursive tree traversals/transformations using Plated that stop
the recursion at a certain point (e.g., upon seeing a certain constructor)

I hope this isn't too vague, but, please, let me know if it is.

/Andrey
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Examples for Control.Lens.Plated?

mantkiew
+1 I've been missing such examples for a long time too. 

Michał

  Original Message  
From: Andrey Chudnov
Sent: Wednesday, September 2, 2015 7:44 PM
To: haskell-cafe
Subject: [Haskell-cafe] Examples for Control.Lens.Plated?

Hello Cafe,
I'm considering porting some of my code that uses uniplate to lens. But
Control.Lens.Plated is giving me headaches. So I'm looking for remedy.

Has anyone used it and willing to share examples? I hope that seeing
some of the combinators in action would help me understand the type
signatures and documentation. What I'm particularly interested in is the
following:
1) implementation of something like transformBi and rewriteBi using lens
2) usage of *On, *Off and *OnOff combinators (e.g., transformMOn,
transformMOff, transformMOnOff). What I want to understand is the
difference between the 3 variants. Also, what does it mean to "Transform
every element in the tree in a region indicated by a supplied Traversal"
and how exactly does the traversal define the region.
3) any recursive tree traversals/transformations using Plated that stop
the recursion at a certain point (e.g., upon seeing a certain constructor)

I hope this isn't too vague, but, please, let me know if it is.

/Andrey
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Examples for Control.Lens.Plated?

Andrey Chudnov
I thought I'd add an example of what I'm trying to do and what I think
transformMOnOff might be very helpful with... that is, if I only knew
how to use it. So suppose I have two mutrec data types,

 > data A = A [A] | B B | I Int
 > data B = B [A]

Suppose I want to write a function

 > incrementByNestingDepth :: A -> A

that would traverse the tree and increment all the I's by their nesting
depth in B, e.g.

 > incrementByNestingDepth (A [I 1, I 3, B [ A [I 2], B [I 1]]]) = A [I
1, I 3, B [A [I 3], B [I 3]]]

I could write that with just recursion on A and B, which could get
tedious if I had several datatypes with 20 constructors each. Or I could
use uniplate. But that's still quite tedious:

 > incrementByNestingDepth a = runState (incrementM a) 0
 > incrementM :: A -> State Int A
 > incrementM a = case a of
 >      I i -> liftM (A . (i +)) get
 >      B b->liftM B $ descendBiM incrementM b
 >      _  -> descendM incrementM a

The code isn't much smaller than for a handwritten traversal and you
could imagine (or take my word for it) that one still doesn't see a lot
of saved space using uniplate with more elaborate examples.

Now, don't get me wrong: I'm not saying uniplate is useless. In fact,
it's one of the most useful libraries I've ever used. It's simple and
does sheer magic more often than not.

However, for the sake of compositionality what (I think) one would like
to do in this case is have two traversals: the outer which says "for
every B, transform its A-children recursively like this" and the inner
says "for every A, transform all of its children recursively, but until
you see a B". You can't really do that with transform/rewrite in
uniplate, so one has to fall back to descend which requires you to set
up your recursion yourself.

The documentation in Control.Lens.Plated alludes that the traversal
above might just be possible using transformOnOff, but, unfortunately,
it does not go into any detail how exactly could one achieve that.

/Andrey

On 09/02/2015 09:31 PM, [hidden email] wrote:

> +1 I've been missing such examples for a long time too.
>
> Michał
>
>    Original Message
> From: Andrey Chudnov
> Sent: Wednesday, September 2, 2015 7:44 PM
> To: haskell-cafe
> Subject: [Haskell-cafe] Examples for Control.Lens.Plated?
>
> Hello Cafe,
> I'm considering porting some of my code that uses uniplate to lens. But
> Control.Lens.Plated is giving me headaches. So I'm looking for remedy.
>
> Has anyone used it and willing to share examples? I hope that seeing
> some of the combinators in action would help me understand the type
> signatures and documentation. What I'm particularly interested in is the
> following:
> 1) implementation of something like transformBi and rewriteBi using lens
> 2) usage of *On, *Off and *OnOff combinators (e.g., transformMOn,
> transformMOff, transformMOnOff). What I want to understand is the
> difference between the 3 variants. Also, what does it mean to "Transform
> every element in the tree in a region indicated by a supplied Traversal"
> and how exactly does the traversal define the region.
> 3) any recursive tree traversals/transformations using Plated that stop
> the recursion at a certain point (e.g., upon seeing a certain constructor)
>
> I hope this isn't too vague, but, please, let me know if it is.
>
> /Andrey
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe