only use functor, not monad