I recently needed to bit rotate the contents of a bytestring producer, and 
was suggested this lens instead of making a getter with "to":

rotatedPB' :: Int -> Lens' (Producer ByteString m x) (Producer ByteString m 
x)
rotatedPB' n = iso (Pipes.ByteString.map (`rotateR` n)) 
(Pipes.ByteString.map (`rotateL` n))

There's a lot of noise in there that motivated me to separate the concepts 
and make other mappings possible while reusing code:

rotated :: Bits a => Int -> Iso' a a
rotated n = iso (`rotateR` n) (`rotateL` n)

mapIso :: ((s -> a) -> b -> t) -> AnIso s a a s -> Iso b t t b
mapIso f l = withIso l $ \sa bt -> iso (f sa) (f bt)

mapIsoWithPipe :: Monad m => ((s -> a) -> Proxy () b c' c m r) -> AnIso s a 
a s -> Iso (Proxy a' a1 () b m r) (Proxy a' a1 c' c m r) (Proxy a' a1 c' c 
m r) (Proxy a' a1 () b m r)
mapIsoWithPipe f = mapIso $ (<-<) . f

pipeMapIsoP :: Monad m => AnIso s a a s -> Iso (Proxy x' x () s m r) (Proxy 
x' x () a m r) (Proxy x' x () a m r) (Proxy x' x () s m r)
pipeMapIsoP = mapIsoWithPipe Pipes.Prelude.map

pipeMapIsoPB :: Monad m => AnIso' Word8 Word8 -> Iso' (Proxy x' x () 
ByteString m r) (Proxy x' x () ByteString m r)
pipeMapIsoPB = mapIsoWithPipe Pipes.ByteString.map

pipeMapIsoPT :: Monad m => AnIso' Char Char -> Iso' (Proxy x' x () Text m 
r) (Proxy x' x () Text m r)
pipeMapIsoPT = mapIsoWithPipe Pipes.Text.map

If pipeMapIsoP is added to Pipes or Pipes.Prelude, and pipeMapIsoPB to 
Pipes.ByteString, users could easily upgrade their lenses for pipe use:

rotatedP :: Bits a => Int -> Lens' (Producer a m r) (Producer a m r)
rotatedP = Pipes.pipeMapIso . rotated

rotatedPB :: Int -> Lens' (Producer ByteString m r) (Producer ByteString m 
r)
rotatedPB = Pipes.ByteString.pipeMapIso . rotated

-- rotatedPT doesn't make sense as Char lacks a Bits instance, but you get 
the idea

If mapIso and mapIsoWithPipe are useful by themselves they could be 
exported too. All the function names are a bit daft, so it would be cool if 
someone came up with better ones. :) Is the idea universal enough to add 
into the core pipes libraries though?

-- 
You received this message because you are subscribed to the Google Groups 
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].

Reply via email to