11
votes

I'd like to stack ResourceT with the ReaderT monad. It seems I have two options: Either place ReaderT on the bottom or at the top of the stack.

data MyEnv

newtype MyT1 m a = MyT1 { unT1 :: ResourceT (ReaderT MyEnv m) a }

newtype MyT2 m a = MyT2 { unT2 :: ReaderT MyEnv (ResourceT m) a }

What would be better in sence of performance/correctness? What are the general guidelines for stacking ResourceT with WriterT or other monads?

1
Interestingly, ResourceT is itself just a specialized ReaderT monad—all of the interesting stuff gets executed in lifted IO actions. I haven't benched it, but my guess is that both stacks are equally fast. Furthermore, Readers commute (via flip) so the two stacks ought to be semantically identical.J. Abrahamson
@J.Abrahamson's comments looks like the right answer to me.Michael Snoyman

1 Answers

1
votes

As far as correctness goes, they are both equally correct -- see comments by @J.Abrahamson and @Michael Snoyman.

Performance probably depends on use, in particular it will change how many calls to lift cross that particular layer, which should be the main performance difference. I'd imagine most fair benchmarks would show little to no difference. For whole program performance, profiling is king.