Remark: we cannot use the caching trick used at
ReplaceExpr because they
may visit the same expression multiple times if they are stored in different memory
addresses. Note that the following code is parametric in a monad
f to each sub-expression of
f t returns false, then t's children are not visited.