On Thu, Jun 28, 2012 at 6:11 PM, Michael Snoyman <mich...@snoyman.com> wrote: > Hi all, > > I'm just about ready to make the 0.5 release of conduit. And as usual, > I'm running up against the hardest thing in programming: naming > things. > > Here's the crux of the matter: in older versions of conduit, functions > would have a type signature of Source, Sink, or Conduit. For example: > > sourceFile :: MonadResource m => FilePath -> Source m ByteString > > I think most people can guess at what this function does: it produces > a stream of ByteStrings, which are read from the given file. > > Now the trick: Source (and Sink and Conduit) are all type synonyms > wrapping around the same type, Pipe. Ideally, we'd like to be able to > reuse functions like sourceFile in other contexts, such as producing a > Conduit that calls sourceFile[1]. However, the type synonym Source > over-specifies some of the type parameters to Pipe, and therefore > `sourceFile` can't be used directly to create a Conduit[2]. > > To get around this whole problem, I've added a number of type synonyms > with rank-2 types, that don't over-specify. You can see the type > synonyms here[3], and more explanation of the problem here[4]. So my > question is: can anyone come up with better names for these synonyms? > Just to summarize here: > > * All of the generalized types start with a G, e.g., Source becomes GSource. > * For Sinks and Conduits, if leftovers are generated, there's an L > after the G (e.g., GLSink). > * For Sinks and Conduits which consume all of their input and then > return the upstream result, we tack on an Inf for Infinite (e.g., > GInfConduit, GLInfSink). > > I think these names are relatively descriptive, and certain `GSink > ByteString m Int` is easier to follow than `Pipe l ByteString o u m > Int`, but I was wondering if anyone had some better recommendations.
I ran into this problem myself with my implementation that used 7 type parameter (the extra parameter wrt to conduit was used by Defer), and I couldn't think of any satisfactory solution. The dilemma here is: - exposing the full `Pipe` type as the primary API would be really confusing for new users - creating a bunch of type synonyms adds a lot of conceptual overhead, and it's actually a leaky abstraction, because `Pipe` will probably be shown in error messages, and appears in the signatures of basic combinators In the end, I gave up the 2 non-essential parameters, built the corresponding lost features on top of `Pipe` using newtypes, and decided to expose a 5-parameter `Pipe` type with no universally quantified synonyms. I'm not sure how easy this Pipe type is to understand, but at least all parameters have a clear meaning that can be explained in the documentation, whereas the `l` parameter is sort of a hack (like my 'd' parameter). BR, Paolo _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe