I really like these. For `pipeMapIsoP` I would add that to `pipes-extras` (I'm trying to keep lens abstractions out of `pipes` to avoid scaring off new users), but the other ones I would be fine adding directly to `pipes-bytestring` (and `pipes-text` if Michael is okay with it).

However, maybe we could make the names prettier. `pipeMapIsoP` could be just `mapIso` and the other ones could be `mapIsoBytes` and `mapIsoChars`. I think the use of the prefix `map` is justified since all three of them should obey these functor laws:

    mapIsoXXX (iso1 . iso2) = mapIsoXXX iso1 . mapIsoXXX iso2
    mapIsoXXX id = id

These three libraries are all designed to be imported qualified, so I don't think we need to worry about trampling namespaces.

If you submit pull requests for `pipes-extras` and `pipes-bytestring` I will accept them.

On 5/25/14, 9:58 AM, Torgeir Strand Henriksen wrote:
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] <mailto:[email protected]>. To post to this group, send email to [email protected] <mailto:[email protected]>.

--
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