Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rewriteOf and transformOf. #119

Merged
merged 2 commits into from
May 26, 2019

Conversation

quasicomputational
Copy link
Contributor

These are taken verbatim from Control.Lens.Plated in lens, commit
206661eb3d502c0430ded9c95b78b5972961dc5c.

I've left the haddocks as they are, mostly because I wasn't sure what to do with the dangling references.

These are taken verbatim from `Control.Lens.Plated` in lens, commit
206661eb3d502c0430ded9c95b78b5972961dc5c.
@neongreen
Copy link
Collaborator

It looks like transformOf and rewriteOf are used very little: https://codesearch.aelve.com/haskell/search?query=\b(transformOf|rewriteOf)\b&insensitive=off&space=off&precise=off&sources=on.

What is your usecase? (Scripting? Library? Application? Switching an existing codebase to lens?)

@quasicomputational
Copy link
Contributor Author

I've found that transformOf is pretty nice for manipulating ASTs, and I'd like to use it in dhall-to-cabal.

@neongreen
Copy link
Collaborator

Alright then! Will merge and release a new version soon after.

@neongreen neongreen merged commit dd911f2 into stevenfontanella:master May 26, 2019
@quasicomputational
Copy link
Contributor Author

Thanks!

@neongreen
Copy link
Collaborator

neongreen commented May 26, 2019

Do you have examples for rewriteOf and transformOf that I could put in the docs? I guess I could do an example with JSON, but it would be better if there were base-only examples as well.

@quasicomputational
Copy link
Contributor Author

Here's a semi-contrived example of using rewriteOf's compositionality for optimisation and separation of concerns:

{-# LANGUAGE LambdaCase #-}

module TinyLang where

import Control.Applicative ( (<|>) )
import Control.Lens ( Traversal', rewriteOf )

data Expr
  = Var String
  | Lit Int
  | Add Expr Expr
  deriving
    ( Eq )

subExprs :: Traversal' Expr Expr
subExprs f = \case
  Var name -> pure ( Var name )
  Lit n -> pure ( Lit n )
  Add a b -> Add <$> f a <*> f b

constantFold :: Expr -> Maybe Expr
constantFold ( Add ( Lit a ) ( Lit b ) ) =
  Just ( Lit ( a + b ) )
constantFold _ =
  Nothing

zeroAdditionIdentity :: Expr -> Maybe Expr
zeroAdditionIdentity ( Add ( Lit 0 ) a ) =
  Just a
zeroAdditionIdentity ( Add a ( Lit 0 ) ) =
  Just a
zeroAdditionIdentity _ =
  Nothing

optimise :: Expr -> Expr
optimise = rewriteOf
  subExprs
  ( \ expr -> constantFold expr <|> zeroAdditionIdentity expr )

example =
  optimise ( Add ( Lit 2 ) ( Add ( Lit (-1) ) ( Lit (-1) ) ) )  == Lit 0

@neongreen
Copy link
Collaborator

Released in microlens-0.4.11.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants