On Fri, Jul 10, 2015 at 9:46 AM, Patrick Chilton <chpatrick@gmail.com> wrote:
Take a look at mono-traversable. pure' is singleton and Foldable' is MonoFoldable.


On Fri, Jul 10, 2015 at 9:47 AM, Patrick Chilton <chpatrick@gmail.com> wrote:
Actually Applicative' is MonoPointed.

Thank you! Indeed, I was able to re-implement the library deferring to MonoFoldable and MonoPointed and then collapse the whole thing to a single module with two functions that automatically work with all suitable input and output types.

In terms of the package (and since I'll be bumping the major version) I don't think the specialized modules are needed any more, since they're just a small subset of the combinatorial input/output space. Or is there a tangible benefit to users in providing more concretely typed versions for those (unusual?) cases where the return type is ambiguous? So, given:

    type Input i e = (MonoFoldable i, Element i ~ e)
    type Output o e = (MonoPointed o, Element o ~ e, Monoid o)

    encode :: forall i o. (Input i Word8, Output o Char) => i -> o
    decode :: forall i o. (Input i Char, Output o Word8) => i -> o

Does including and exposing the following...

    encodeToString :: Input i Word8 => i -> [Char]
    decodeToBytes :: Input i Char => i -> [Word8]
    encodeBytes :: Output o Char => [Word8] -> o
    decodeString :: Output o Word8 => [Char] -> o
    encodeBytesToString :: [Word8] -> [Char]
    decodeStringToBytes :: [Char] -> [Word8]

...add any value, being trivially defined as equal to the generic version? (Plus, the explosion doubles with another dimension like lazy vs. strict.) I don't see much advantage over e.g. (encode ws :: String) for the first case.

Thanks again,