re-factored to use monad transformer