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 = 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) -> forall (m :: * -> *) a. Monad m => a -> m a return (forall byte. ByteCompatible byte => byte -> Word8 toByte byte c, [byte] cs) [byte] _ -> 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 s xs <- forall (m :: * -> *) s. Monad m => StateT s m s State.get (Word8 c,s cs) <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a. (MonadTrans t, Monad m) => m a -> t m a lift (forall s (m :: * -> *). (ByteStream s, MonadFail m) => s -> m (Word8, s) getWord8 s xs) forall (m :: * -> *) s. Monad m => s -> StateT s m () State.put s cs forall (m :: * -> *) a. Monad m => a -> m a return Word8 c