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].
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].

Reply via email to