
> Imagine a generalized version of replace that 1) works on streams, and
> replace' :: Stream (Stream (Of Text) m) m () > -> Stream (Stream (Of Text) m) m Void > -> Stream (Of Text) m r > -> Stream (Of Text) m r > > > Do you find easy to intuit, just by looking at that signature, which > is the function of each argument?
Absolutely not. In fact, this crossed my personal complexity horizon and is still accelerating towards some kind of singularity.
I agree 100%. What is going on here? If you just wanted to clarify the signature, why not just use type synonyms? type Replaced = Text type Replacement = Text replace :: Replaced -> Replacement -> Text -> Text No breaking changes necessary. You don't even have to export the synonyms. Or generalize the function in a much simpler fashion: replace :: (Text -> Text) -> Text -> Text There should be no ambiguity here. It's less powerful than the stream-monster because the argument function is stateless - but then whatever kind of stream you use probably has some zipWith function that you could use for more complicated cases.
A possible use case: you want to "splice" the contents of a sequence of files into another file at certain words, without having to keep whole files in memory, and without using lazy I/O.
I'm not really familiar with streams or pipes, but that does sound like a perfect use case for conduits. Still, I'm at a loss how that thing would look internally. How do you "find" a stream of Text in another Text? What does that even mean, semantically? So if I understand the use case correctly, you have some "trigger words" in a Text and want to replace each trigger with the contents of a file, as in a templating system. The simplest type I could come up with for that would be replace' :: Map Text (Stream (Of Text) m ()) -> Stream (Of Text) m r -> Stream (Of Text) m r Note: No Stream on the left side of an arrow. No Stream of triggers, so ordering is not important anymore. It wasn't helpful anyway. Easily generalized to non-text stuff. And as such it may already be part of some streaming libraries. Which is exactly as it should be: streaming functions should be part of streaming libraries, not a text library.