rewrite bug duplicate code to functor style