<div dir="ltr"><div>OK, so just deriving the instances doesn't yield the expected behavior, because the `Var` case explicitly mentions `Id`s instead of the type parameter `b`.</div><div>Even if that would be changed, it's not easy to pin down over which parts of the syntax tree we should 'map'.</div><div>Should we include binding sites of local variables? I'm inclined to say No, but only because I have my concrete use case in mind.</div><div><br></div><div>It's probably best to have non-derived, non-typeclass functions `foldMapVars :: Monoid m => (Id -> m) -> Expr b -> m`, or a variant where the mapping function also gets supplied a value of `data NameSite = Lam | Let | VarRef` (for lack of a better name).<br></div></div><br><div class="gmail_quote"><div dir="ltr">Am Mo., 18. Juni 2018 um 14:43 Uhr schrieb Sebastian Graf <<a href="mailto:sgraf1337@gmail.com">sgraf1337@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi everyone,</div><div><br></div><div>I'm repeatedly wondering why there are no `Functor`, `Foldable` and `Traversable` instances for `Expr`.</div><div><br></div><div>Is this just by lack of motive? <br></div><div>I could help there: I was looking for a function that would tell me if an expression mentions `makeStatic`. After spending some minutes searching in the code base, I decided to roll my own thing in `CoreUtils`.</div><div>I really couldn't think about a good name, so I settled for `anyReferenceMatching :: (b -> Bool) -> Expr b -> Bool` and realized that I could generalize the function to `foldMapExpr :: Monoid m => (b -> m) -> Expr b -> m`.</div><div><br></div><div>Occasionally this need pops up and I really want to avoid writing my own traversals over the syntax tree. So, would anyone object to a patch implementing these instances?</div><div><br></div><div>Thanks</div><div>Sebastian<br></div></div>
</blockquote></div>