7 ms·
So let me try to see if I get it. You change the signature of your I/O functions to return a self defined monad called World. To make sure this works in product
by tinco 11y ago
So let me try to see if I get it. You change the signature of your I/O functions to return a self defined monad called World. To make sure this works in production you make World an instance of I/O so it can be ran by your regular main.
Then for the test suite, you make an instance of World that keeps a state monad and mock implementations of the I/O functions that return/change that state instead of having undeterministic side effects.
The whole process seems logical, but the Haskell is rather ugly. Surely someone has written a DSL or library to make working like this a little easier? Especially defining the FakeState monad with S.modify calls looks like a pain.
- mralston 11y agoThe thing is that while the implementation of the fake can get ugly, that's effectively library code that's written once - the actual application code is incredibly clean since all you have to do to it is tag it as being World instead of IO. Likewise, for tests, the actual interface in practice is clean - we have a few fake-World-only setup functions, and when testing things like the database we can just use the regular insert interface to do our setup.