A Question on dummy types

13 views
Skip to first unread message

Yan Huang

unread,
May 9, 2017, 11:06:35 AM5/9/17
to Haskell Pipes
In the Appendix section of the tutorial (https://hackage.haskell.org/package/pipes-4.3.3/docs/Pipes-Tutorial.html), it defines an inhabited "data X" to mask the backward flow of the "Proxy" type. It seems that the null type "()" is also used for the same purpose, while the choice of X and () as a dummy type looks arbitrary. Are there any differences or am I missing something?

Thanks!

David McBride

unread,
May 9, 2017, 11:30:14 AM5/9/17
to haskel...@googlegroups.com
data X has no inhabitants. () has exactly one inhabitant, which is ().

This means that you can constuict a (), but you cannot construct an X.

Inn practice with pipes that means that if a part of the Pipe type is
set to (), you can use yield () in your code. But you cannot yield
(??? :: X) because X has no constructor.

By the time you've connected a producer to a consumer you have a full
Effect type, it should not be sending items up or down stream, () or
otherwise, so it blocks off both of those variables in the Effect type
to force your code to adhere to that on the type level.
> --
> 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 haskell-pipe...@googlegroups.com.
> To post to this group, send email to haskel...@googlegroups.com.

Yan Huang

unread,
May 9, 2017, 11:59:56 AM5/9/17
to haskel...@googlegroups.com
Thanks, David! Your explanation helps. But one more question appears,

Why isn't the Producer defined as follows 
      type Producer b = Proxy X () X b
(where both ends of the upstream are assured to be blocked)
or defined as
      type Producer b = Proxy X X X b
(where it is guaranteed that the producer can't take in anything from the source of the downstream)?



> To post to this group, send email to haskel...@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "Haskell Pipes" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/haskell-pipes/gLSIj_E9RSc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to haskell-pipes+unsubscribe@googlegroups.com.

David McBride

unread,
May 9, 2017, 12:56:06 PM5/9/17
to haskel...@googlegroups.com
Pipes is actually bi directional. However most common usage of pipes
is unidirectional where elements flow downstream.

When you have a unidirectional pipe what is actually happening is you
are sending elements downstream, and then you are sending () upstream
when you want another chunk. The unidirectional pipe upstream from
you gets that () and uses that as a signal to send its next chunk back
downstream.

await and yield are actually implemented using the bidirectional pipe
functions request and respond. You can see this in the source where
they are defined as such:

yield :: Monad m => a -> Producer' a m ()
yield = respond

await :: Monad m => Consumer' a m a
await = request ()

Where respond takes the element sent downstream, and returns ().
Await sends () upstream and returns an element.
>> > email to haskell-pipe...@googlegroups.com.
>> > To post to this group, send email to haskel...@googlegroups.com.
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "Haskell Pipes" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/haskell-pipes/gLSIj_E9RSc/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> haskell-pipe...@googlegroups.com.
>> To post to this group, send email to haskel...@googlegroups.com.
>
>
> --
> 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 haskell-pipe...@googlegroups.com.

Gabriel Gonzalez

unread,
May 11, 2017, 12:30:39 AM5/11/17
to haskell-pipes
The reason we don't define:

      type Producer b = Proxy X () X b

... is because you can't actually create a (useful) `Producer` of that type.  If you had a `Producer` of that type then the return value of `respond` (which is like `yield` but with a more general type) would be `X` which could be transformed into value of any type, but that's not possible unless you cheat and return `undefined` or something similar.  The only `Producer` that can have that type (without cheating) is one that never `yield`s or `respond`s.

That's also the same reason why we don't define:

      type Producer b = Proxy X X X b

As long as the third type parameter is `X` you can't `respond` or `yield`



>> > To post to this group, send email to haskel...@googlegroups.com.
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "Haskell Pipes" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/haskell-pipes/gLSIj_E9RSc/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to

>> To post to this group, send email to haskel...@googlegroups.com.
>
>
> --
> 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

> To post to this group, send email to haskel...@googlegroups.com.

--
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 haskell-pipes+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages