@@ -170,17 +170,66 @@ unpin arr@(MutableByteArray marr#) =
170170-- size and alignment. We can possibly write tests for checking compatibility
171171-- with Storable.
172172
173−-- | An 'Unbox' type supplies operations for reading and writing the type
174−-- from and to a byte array in memory. The read operation constructs the boxed
175−-- type from an unboxed byte representation in memory. The write operation
176−-- writes the boxed type to an unboxed byte representation in memory.
173+-- | A type implementing the 'Unbox' interface supplies operations for reading
174+-- and writing the type from and to a mutable byte array (an unboxed
175+-- representation) in memory. The read operation 'peekByteIndex' constructs the
176+-- boxed type from the mutable byte array. The write operation 'pokeByteIndex'
177+-- writes the boxed type to the mutable byte array.
177178--
178−-- This type class dependes on Storable for size and alignment of the type. It
179−-- is similar to Storable in the sense that it has corresponding operations for
180−-- peekByteOff and pokeByteOff. While Storable allows writing to a Ptr, this
181−-- type class allows writing to a MutableByteArray#.
179+-- This type class depends on the 'Storable' for 'sizeOf' and 'alignment'
180+-- operations. While 'Storable' supplies the ability to serialize a type to a
181+-- 'Ptr' type, 'Unbox' augments it by supplying the ability to serialize to a
182+-- mutable byte array. The advantage of 'Unbox' over 'Storable' is that we can
183+-- use unpinned memory with 'Unbox'.
184+--
185+-- Note: Use the @QuantifiedConstraints@ language extension so that you can
186+-- just use a single 'Unbox' constraint in your code rather than using both
187+-- 'Storable' and 'Unbox'.
188+--
189+-- Here is an example, to write an instance for this type class.
190+--
191+-- >>> :{
192+-- data Object = Object
193+-- { _int0 :: Int
194+-- , _int1 :: Int
195+-- }
196+-- :}
197+--
198+-- Note you can leave peek and poke undefined in 'Storable' if you are not
199+-- using the Storable instance, Unbox does not need these operations.
200+--
201+-- >>> import Foreign.Ptr (plusPtr, castPtr)
202+-- >>> import Foreign.Storable (Storable(..))
203+-- >>> :{
204+-- instance Storable Object where
205+-- sizeOf _ = 16
206+-- alignment _ = 8
207+-- peek ptr = do
208+-- let p = castPtr ptr
209+-- x0 <- peek p
210+-- x1 <- peek (p `plusPtr` 8)
211+-- return $ Object x0 x1
212+-- poke ptr (Object x0 x1) = do
213+-- let p = castPtr ptr
214+-- poke p x0
215+-- poke (p `plusPtr` 8) x1
216+-- :}
217+--
218+-- >>> import Streamly.Data.Array (Unbox(..))
219+-- >>> import Streamly.Internal.Data.Unboxed (castContents)
220+-- >>> :{
221+-- instance Unbox Object where
222+-- peekByteIndex arr i = do
223+-- let p = castContents arr
224+-- x0 <- peekByteIndex p i
225+-- x1 <- peekByteIndex p (i + 8)
226+-- return $ Object x0 x1
227+-- pokeByteIndex arr i (Object x0 x1) = do
228+-- let p = castContents arr
229+-- pokeByteIndex p i x0
230+-- pokeByteIndex p (i + 8) x1
231+-- :}
182232--
183−-- Note: Enable @QuantifiedConstraints@ to simplify constraint specification.
184233class Storable a => Unbox a where
185234 -- | Read an element of type "a" from a MutableByteArray given the byte
186235 -- index.