Overview

Monad Tell

MonadTell is used to return additional non-output data that is generated during a computation. For example, it can provide some sort of analysis of the computation we have just performed. It's default implementation is WriterT.

Since we can only return one object and we want to return something in addition to the output, we'll need to return a Tuple that wraps the output and additional data. In cases where we already have non-output data and need to "store" another value of non-output data, we'll need to combine the two together, which implies a Semigroup. Lastly, to implement Applicative, we will need an "empty" value of that data, which implies Monoid.

Putting this into code, we get this:

             -- w               m     a
newtype WriterT non_output_data monad output =
  WriterT (monad (Tuple output non_output_data))

-- Pseudo-syntax: combines the type class and instance into one block
class (Monoid w, Monad m) <= MonadTell w (WriterT w m) where
  tell :: w -> m Unit
  tell w = WriterT (pure (Tuple unit w))

Do Notation

Since tell returns an m Unit, which will be discarded in do notation, we'll only be writing:

useReader :: Reader NonOuputData Output
useReader = do                                                          {-
  unit <- tell nonOuputData                                             -}
          tell nonOuputData
  -- without indentation
  tell nonOuputData

Monad Writer

MonadWriter extends MonadTell by enabling a computation's non-output data to be

  • appended via tell and then exposed in the do notation for later usage (listen)
  • appended via tell after it is modified by a function (pass)

Derived Functions

MonadTell does not have any derived functions.

MonadWriter has two:

  • listens: same as listen but modifies the non-output data before exposing it to the do notation
  • censor: modifies the non-output data returned by a computation before appending it via tell.

Laws, Instances, and Miscellaneous Functions

For their laws, see

For WriterT's instances:

To handle/modify the output of a writer computation: