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 a function in Control.Lens.Plated to fold multiple plated things at once? #776

Open
benjamin-hodgson opened this Issue Dec 11, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@benjamin-hodgson
Contributor

benjamin-hodgson commented Dec 11, 2017

I sometimes find the following generic function useful:

zipPara :: Plated a => ([a] -> [r] -> r) -> [a] -> r
zipPara f xs = f xs $ zipPara f <$> alaf ZipList traverse (toListOf plate) xs

It's like para, except it consumes multiple as at once, zipping together the children from each a's plate. So the list of rs that gets passed to the function is the length of the shortest plate in xs.

Useful for, eg, testing two trees for equality, if for whatever reason you don't want to use the derived ==:

data Expr = Lit Int | Add Expr Expr

eq :: Expr -> Expr -> Bool
eq x y = zipPara (\[x, y] children -> and (eqOneLayer x y : children)) [x, y]
    where
        eqOneLayer (Lit x) (Lit y) = x == y
        eqOneLayer (Add _ _) (Add _ _) = True
        eqOneLayer _ _ = False

Would you guys be interested in a PR to add (a suitably optimised version of) this function (and a zipParaOf sibling) to the Plated module?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment