Why does Haskell not have an I Monad (for input only, unlike the IO monad)?

后端 未结 5 1207
攒了一身酷
攒了一身酷 2021-02-18 15:29

Conceptually, it seems that a computation that performs output is very different from one that performs input only. The latter is, in one sense, much purer.

I, for one,

5条回答
  •  清歌不尽
    2021-02-18 15:52

    The 'Input' side of the IO monad is just as much output as it is input. If you consume a line of input, the fact that you consumed that input is communicated to the outside, and also serves to be recorded as impure state (ie, you don't consume the same line again later); it's just as much an output operation as a putStrLn. Additionally, input operations must be ordered with respect to output operations; this again limits how much you can separate the two.

    If you want a pure read-only monad, you should probably use the reader monad instead.

    That said, you seem to be a bit confused about what combining monads can do. While you can indeed combine two monads (assuming one is a monad transformer) and get some kind of hybrid semantics, you have to be able to run the result. That is, even if you could define an IT (OT Identity) r, how do you run it? You have no root IO monad in this case, so main must be a pure function. Which would mean you'd have main = runIdentity . runOT . runIT $ .... Which is nonsense, since you're getting impure effects from a pure context.

    In other words, the type of the IO monad has to be fixed. It can't be a user-selectable transformed type, because its type is nailed down into main. Sure, you could call it I (O Identity), but you don't gain anything; O (I Identity) would be a useless type, as would be I [] or O Maybe, because you'd never be able to run any of these.

    Of course, if IO is left as the fundamental IO monad type, you could define routines like:

    runI :: I Identity r -> IO r
    

    This works, but again, you can't have anything underneath this I monad very easily, and you're not gaining much from this complexity. What would it even mean to have an Output monad transformed over a List base monad, anyway?

提交回复
热议问题