using free monad