Lenses are a key aspect of `pipes-parse`. Asking for a lens-free subset
of `pipes-parse` in order to avoid using lenses is analogous to asking
for a `Pipe`-free subset of `pipes` in order to avoid using the `(>->)`
operator.
I truly believe lenses should be the sole API for `pipes-parse`. Also,
`lens-family-core` is a really tiny dependency, so I don't feel bad
about asking users to depend on it to use `pipes-parse`.
However, the use of lenses for `pipes-group` (i.e. the `FreeT` lenses)
is not strictly necessary and is only for code reuse. So if you want I
can propose a compromise: keep `pipes-parse` lenses, add the `debugXXX`
functions, and add the following non-lens versions of `pipes-group`
functions:
* For all `FreeT` lenses, provide the `view` (i.e. the splitter)
* For all `FreeT` isomorphisms, provide the reverse view (i.e. the
joiner) if it's not already in the API (example: `unlines`)
On 02/12/2014 06:34 PM, Kyle Van Berendonck wrote:
I thought I had already replied to this, but I must have forgotten to
get back and post it.
I dislike this solution because it's forcing people into doing things
they don't want to do. You don't need to provide all three; view, zoom
and over -- that's un-necessary because if people need those they can
just use the lenses, but you do need to provide a "complete" API so
that someone can actually build a simple program with the option to
extend it later with lenses when they feel more comfortable.
This means for example, `view decoded` is an important skeleton to
provide and so is `encoder`.
Adding these debugging functions may fix the problem, but the solution
is not the correct one. It's putting a lot of pressure on the user to
feel that these errors are as a fault of them not being able to deal
with the types produced by the libraries, rather than the more correct
opinion that the libraries have made lens (an extension for seasoned
users) the sole API, which (IMO) is wrong.
Regards.
On Tuesday, February 11, 2014 4:42:42 PM UTC+11, Gabriel Gonzalez wrote:
Ok, I think I found an approach that will satisfy everybody. This
solution only requires providing three utility functions in
`pipes-parse`:
debugView
:: (Producer a m x -> Producer b m y)
-> (Producer a m x -> Producer b m y)
debugView = id
debugZoom
:: (StateT (Producer a m x) m r -> StateT (Producer b m y)
m r)
-> (StateT (Producer a m x) m r -> StateT (Producer b m y)
m r)
debugZoom = id
debugOver
:: ( (Producer a m w -> Producer b m x)
-> (Producer c m y -> Producer d m z) )
-> ( (Producer a m w -> Producer b m x)
-> (Producer c m y -> Producer d m z) )
debugOver = id
The following example shows how you would use it (see the `p3`
example):
http://lpaste.net/99760
Notice how the type error is actually even *better* now than the
"intermediate function" proposal.
There also need to be equivalent type-restriction functions for
`FreeT` transformations as well. Those will go in `pipes-group`.
The nice advantages of this solution are:
* There's no longer a need to provide three extra functions for
every lens (i.e. one each for `view`/`zoom`/`over`)
* The user doesn't need to know what the restricted type should
be. The utility functions take care of that.
* It's very easy to undo once the user has found the correct type,
by deleting the `debugXXX` function. This leaves the user with
idiomatic lens-based code.
On 02/10/2014 02:51 PM, Kyle Van Berendonck wrote:
I don't think teaching users how to "hack around" the titanic
type error issue is really a solution though, and certainly not
in pipes-parse because people who are interested in a particular
pipes library are less likely to read it there.
On Monday, February 10, 2014 3:28:13 AM UTC+11, Gabriel Gonzalez
wrote:
So I was thinking some more about this, and I was wondering
if perhaps the solution would be to simply explain in the
`pipes-parse` tutorial how to simplify type errors using the
trick of defining an intermediate non-lens function.
The tutorial would say (in more words) that if you have a
type error with a `lens` of type `Lens (Producer a m x)
(Producer b m y)` while using `view`, then you should convert
it to an intermediate ordinary function like this:
intermediate :: Producer a m x -> Producer b m y
intermediate = view lens
... then use that `intermediate` function for better type
error inference. Similarly, if you have a type error using
the `lens` with a `zoom`, then you convert it to the
following intermediate ordinary function:
intermediate:: StateT (Producer b m y) m r -> StateT
(Producer a m x) m r
intermediate = zoom lens
Teaching beginners how to do this would help them improve
type errors without having to add redundant functions to the API.
--
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] <javascript:>.
To post to this group, send email to [email protected]
<javascript:>.
--
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].
--
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].