<p dir="ltr">What I would do is hold the function to apply in the wrapper type.</p>
<p dir="ltr">import qualified Data.ByteString as BS</p>
<p dir="ltr">data ByteString' a = ByteString' (Word8 -> a) BS.ByteString</p>
<p dir="ltr">wrap :: BS.ByteString -> ByteString' Word8<br>
wrap bs = ByteString' id bs</p>
<p dir="ltr">-- The type ensures you can only unwrap with a function Word8 -> Word8.<br>
unwrap :: ByteString' Word8 -> ByteString<br>
unwrap (ByteString' f bs) = BS.map f bs</p>
<p dir="ltr">-- Functor instance just concatenates the fmapped function.<br>
instance Functor ByteString' where<br>
    fmap f (ByteString' g bs) = ByteString' (f . g) bs</p>
<p dir="ltr">-- Foldable instance just uses the fmapped function.<br>
instance Foldable ByteString' where<br>
    foldr f z (ByteString' g bs) = BS.foldr (f . g) z bs<br>
-- You could define foldr', foldl, etc. based on the ones in Data.ByteString.<br>
-- Not strictly necessary, but nice to have.</p>
<p dir="ltr">As an added benefit, this doesn't require GADTs. It probably would if you wanted to implement Monad as well, though.</p>
<div class="gmail_quote">On Feb 28, 2015 1:11 PM, "silvio" <<a href="mailto:silvio.frischi@gmail.com">silvio.frischi@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I have recently heard that some people want to burn bridges (introducing<br>
Foldable and Traversable to Prelude) and I've been wondering if it was<br>
possible somehow allow Text and Bytestring like containers to make use<br>
of those functions. Something along the lines of<br>
<br>
import qualified Data.ByteString as BS<br>
<br>
newtype ByteString' a = ByteString' BS.ByteString<br>
<br>
type ByteString = ByteString' Word8<br>
<br>
instance (ByteString' a ~ ByteString' Word8) => Functor (ByteString')<br>
    where<br>
        fmap f (ByteString' bs) = ByteString' $ BS.map f bs<br>
<br>
<br>
Or if DataContexts worked as you would expect.<br>
<br>
newtype (Word8 ~ a) => ByteString' a = ByteString' BS.ByteString<br>
<br>
However I couldn't find a solution and I was just wondering if it is<br>
possible.<br>
<br>
P.S. Using GADTS it does actually work for Foldable, but only because it<br>
doesn't have to output any ByteStrings. It doesn't work for Functor for<br>
instance.<br>
<br>
data ByteString' a where<br>
        ByteString' :: BS.ByteString -> ByteString' Word8<br>
<br>
type ByteString = ByteString' Word8<br>
<br>
instance Foldable ByteString' where<br>
        foldr f ini (ByteString' bs) = BS.foldr f ini bs<br>
<br>
<br>
Silvio<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>