The core datatypes of Data.ByteString.Builder
are
newtype Builder = Builder (forall r. BuildStep r -> BuildStep r)
type BuildStep a = BufferRange -> IO (BuildSignal a)
data BuildSignal a =
Done {-# UNPACK #-} !(Ptr Word8) a
| BufferFull
{-# UNPACK #-} !Int
{-# UNPACK #-} !(Ptr Word8)
(BuildStep a)
| InsertChunk
{-# UNPACK #-} !(Ptr Word8)
S.ByteString
(BuildStep a)
What purpose does the type parameter (r
or a
) serve?
ST
– it prevents you from using pointers in a context where the data doesn't exist. – Chapitera
inDone
constructor. – VaticanST
or do you maybe have a reference? – DomenigaST
monad has an extras
parameter that's not actually used for anything. The type system ensures this parameter is “synchronised” along any given mutable computation. For actually getting any result out of such a computation, you need to userunST
, whose Rank-2 type prevents you from fixing thes
to anything particular. So if you smuggle out a reference to e.g. a mutable array out of such a computation, there is you can do with it elsewhere, because thes
type doesn't match. – Chapiter