    module Data.Accessor.ByteSource where

    import qualified Control.Monad.Trans.State as State
    import Control.Monad.Trans.State (StateT, )
    import Control.Monad.Trans.Class (lift, )
    import Data.Word (Word8, )

    class ByteCompatible byte where
       toByte :: byte -> Word8

    instance ByteCompatible Word8 where
       toByte :: Word8 -> Word8
    toByte = Word8 -> Word8
    forall a. a -> a
    id

    class ByteStream s where
       getWord8 :: MonadFail m => s -> m (Word8, s)

    instance ByteCompatible byte => ByteStream [byte] where
       getWord8 :: forall (m :: * -> *). MonadFail m => [byte] -> m (Word8, [byte])
    getWord8 [byte]
    xs =
          case [byte]
    xs of
             (byte
    c:[byte]
    cs) -> (Word8, [byte]) -> m (Word8, [byte])
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (byte -> Word8
    forall byte. ByteCompatible byte => byte -> Word8
    toByte byte
    c, [byte]
    cs)
             [byte]
    _ -> String -> m (Word8, [byte])
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "ByteStream: no more byte available"

    class Monad source => ByteSource source where
       readWord8 :: source Word8

    instance (ByteStream s, MonadFail m) => ByteSource (StateT s m) where
       readWord8 :: StateT s m Word8
    readWord8 =
          do xs <- StateT s m s
    forall (m :: * -> *) s. Monad m => StateT s m s
    State.get
             (c,cs) <- lift (getWord8 xs)
             State.put cs
             return c