
I was hoping to use Haskell's laziness to implement some of the stuff from "Continuation and Transducer Composition" (http://www-static.cc.gatech.edu/~shivers/papers/fcoro.pdf) a bit more elegantly, without manually coding the coroutine logic in continuation-passing style. Unfortunately, I'm beginning to think there is no workaround. Here's the challenge in a simplified form: newtype Source x = Source (x, Source x) newtype Sink x = Sink (x -> Sink x) type SourceTransducer x y = Source x -> Source y type SinkTransducer x y = Sink y -> Sink x sourceToSinkTransducer :: SourceTransducer x y -> SinkTransducer x y I can't find any way to implement the sourceToSinkTransducer function and its inverse. This is disappointing, because SourceTransducer and SinkTransducer are obviously isomorphic and there are languages like Oz that can accomplish this. Tell me I'm missing something obvious?

Mario Blazevic wrote:
newtype Source x = Source (x, Source x) newtype Sink x = Sink (x -> Sink x)
type SourceTransducer x y = Source x -> Source y type SinkTransducer x y = Sink y -> Sink x
sourceToSinkTransducer :: SourceTransducer x y -> SinkTransducer x y
I can't find any way to implement the sourceToSinkTransducer function
Indeed that cannot be done because it breaks referential transparency. A Source is isomorphic to a list, so I'll call it that. Referential transparency implies that you must know the complete list before you can pass it to the SourceTransducer - you can not later change list elements or fork into different versions of the list. On the other hands, sinks allow you to do exactly that, you can take one sink and apply it to two different values. This means that you have to consume the entire infinite input to a sink before you can pass it to your source transducer. In other words, it cannot be done.
and its inverse.
You cannot make any interesting observations of a Sink; whatever functions you put there can't have any side effects. I think this is impossible, too. Food for thought: You need some sort of side effects (I'm not quite sure which), so it'd be interesting to try newtype Source m x = Source (m (x, Source x)) newtype Sink m x = Sink (x -> m (Sink x)) where m is an appropriate monad. Will the continuation monad work? regards, Bertram Felgenhauer
participants (2)
-
Bertram Felgenhauer
-
Mario Blazevic