Arrows and the IO monad

Peter Simons simons@cryp.to
14 Apr 2003 19:31:06 +0200


Hi,

after reading the excellent paper "Generalising Monads to Arrows" from
John Hughes, I am trying to use an arrow-based stream processor of
type 'SP a b' to implement a network daemon. So far I have defined the
arrow successfully:

> data SP a b = Put b (SP a b)
>             | Get (a -> SP a b)
>             | Null
>               deriving (Show)
>
> instance Arrow SP where
>     arr f = get (\x -> put (f x) (arr f))
>
>     _ >>> Null           = Null
>     sp1 >>> Put c sp2    = Put c (sp1 >>> sp2)
>     Null >>> Get _       = Null
>     Put c sp1 >>> Get f2 = sp1 >>> f2 c
>     Get f1 >>> Get f2    = Get (\c -> f1 c >>> Get f2)
>
>     first f = bypass [] f
>         where
>         bypass ds (Get f)        = Get (\(b,d) -> bypass (ds ++ [d]) (f b))
>         bypass [] (Put c sp)     = Get (\(_,d) -> Put (c,d) (bypass [] sp))
>         bypass (d:ds) (Put c sp) = Put (c,d) (bypass ds sp)

But now I have to make the stream processors interact with the IO
monad, because I want the actual reading and writing to take place in
the processor arrow. Is there any good way to achieve that without
being forced to use the type 'SP (IO a) (IO b)' throughout the arrow?

Can I maybe split the data flow for simple non-IO processors off the
I/O monad temporarily?

Or is there a way to combine my SP arrow with the IO monad in way that
IO actions can be lifted to my SP arrow?

Can anyone recommend some further reading material concerning this
topic?

Any feedback is appreciated!

Peter