10

Is it necessary to have access to the internal structure of a monad to write the monad transformer?

For example: I'd like to have GetT - transformer for Get monad from Data.Binary.Get, but this module doesn't expose internals of Get monad. Does it mean that the only way for me is to add GetT directly to Data.Binary.Get module?

Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192
Victor Denisov
  • 717
  • 5
  • 13
  • 2
    I think usually it's the other way around. It's the monad transformer that defines the real implementation of the monad, and then you apply it to the `Identity` monad in order to obtain the "basic" instance of that monad (e.g. you apply `StateT` to `Identity` to get `State`). Beware, I'm not sure of this :) – Riccardo T. Aug 03 '12 at 08:54

1 Answers1

11

In general, yes. See in this example how the the inner monad (here the list monad) can “undo” the effect of an “earlier” action of the outer monad:

> execWriterT (tell "Hi" >> tell "Ho" >> lift [()])
["HiHo"]
> execWriterT (tell "Hi" >> tell "Ho" >> lift [])
[]

Now assume you could turn every monad into a monad transformer. Then you would be able to construct a IOT monad transformer, and this could would launch a missile but then undo it:

> execIOT (launchMissile >> lift [])

Hence it is not possible to turn an arbitrary monad, without looking at the definition, into a monad transformer.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
  • Do I understand correctly that you give this case as an example where you don't need information about inner structure? But you actually use the fact that inner monad is list. – Victor Denisov Aug 03 '12 at 12:33
  • No; the inner structure in question is that of the monad that you want to turn into a transformer, in this case `IO` (and in your case `Get`). You never need information about the inner structure of the monad that you want to wrap. That leads to the question why you want a `GetT` transformer in the first place, i.e. what do you want to achieve? – Joachim Breitner Aug 03 '12 at 13:33
  • I have some code where I communicate over socket using Handler. – Victor Denisov Aug 03 '12 at 13:40
  • There is have a data structure I'd like to parse from the Handler. I also need to communicate using console and to write something to the handler(do some IO operations). I'd like to do hGetContents and let Get monad to keep track of how much data has been parsed. – Victor Denisov Aug 03 '12 at 13:53
  • 1
    If the question is 'is access to the internal structure required to write a monad transformer', wouldn't the answer be 'yes'? – John L Aug 03 '12 at 13:54
  • 1
    @VictorDenisov - given those requirements, you may want to look into one of the various iteratee flavors (iteratee,conduit,pipes, lots of options). That problem is pretty much directly in their design space. – John L Aug 03 '12 at 13:55
  • Why would `execIOT (launchMissile >> lift [])` have to first launch a missile and then "undo" it? I would expect that the expression `launchMissile >> lift []` is simply an `IOT []` value that _does not_ launch any missiles, so then `execIOT` doesn't have to do anything when executing it. – winitzki Mar 05 '19 at 01:09