Can anybody explain GHC's definition of IO?

前端 未结 3 1382
悲哀的现实
悲哀的现实 2021-01-13 10:23

The title is pretty self-descriptive, but there\'s one part that caught my attention:

newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
         


        
3条回答
  •  鱼传尺愫
    2021-01-13 11:00

    It's probably best not to think too deeply about GHC's implementation of IO, because that implementation is weird and shady and works most of the time by compiler magic and luck. The broken model that GHC uses is that an IO action is a function from the state of the entire real world to a value paired with a new state of the entire real world. For humorous proof that this is a strange model, see the acme-realworld package.

    The way this "works": Unless you import weird modules whose names start with GHC., you can't ever touch any of these State# things. You're only given access to functions that deal in IO or ST and that ensure the State# can't be duplicated or ignored. This State# is threaded through the program, which ensures that the I/O primitives actually get called in the proper order. Since this is all for pretend, the State# is not a normal value at all—it has a width of 0, taking 0 bits.

    Why does State# take a type argument? That's a much prettier bit of magic. ST uses that to force polymorphism needed to keep state threads separate. For IO, it's used with the special magic RealWorld type argument.

提交回复
热议问题