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