Module WithMonadAndLog.WithMonad

type t('a, 'w) = WithMonad(Monad).t('a'w) =
| WriterT(Monad.t(('a, 'w)))
;
let make: Monad.t(('a, 'w)) => t('a'w);
let runWriterT: t('a'w) => Monad.t(('a, 'w));
let execWriterT: t('a'w) => Monad.t('w);
let mapWriterT: (Monad.t(('a, 'w)) => Monad.t(('b, 'w))) => t('a'w) => t('b'w);
let tell: 'w => t(unit, 'w);
let listen: t('a'w) => t(('a, 'w)'w);
let pass: t(('a, ('w => 'w))'w) => t('a'w);
let listens: ('w1 => 'w2) => t('a'w1) => t(('a, 'w2)'w1);
let censor: ('w => 'w) => t('a'w) => t('a'w);
let map: ('a => 'b) => t('a'w) => t('b'w);
let applyWithAppendLog: ('w => 'w => 'w) => t('a => 'b'w) => t('a'w) => t('b'w);
let pureWithEmptyLog: 'w => 'a => t('a'w);
let bindWithAppendLog: ('w => 'w => 'w) => t('a'w) => ('a => t('b'w)) => t('b'w);
module WithLog: (Log: WriterLog.LOG) => { ... };

In order to implement the common typeclasses, we need to know how to append log entries (in most cases). In Haskell/Purescript/Scala/etc. many of the typeclass instances depend on various other specific typeclasses, but here, we are just normalizing on WriterLog, which contains a type for collecting logs, and a Monoid for the type.