[Haskell-cafe] Stream processors
Jeremy Shaw
jeremy.shaw at linspireinc.com
Thu Oct 21 13:55:59 EDT 2004
At 21 Oct 2004 16:48:57 +0200,
Peter Simons wrote:
>
> Hi,
>
> I know the stream processors as described in Hughes' paper
> about Arrows, but those are pure stream processors -- they
> don't allow for I/O, which I need to handle the Ptr.
Here is a some code I scraped off the net a while ago, though I can't
seem to find the origin anymore. Not sure what the license is. Also, I
think it might be a little buggy -- I have not used it much...
However, it does show how to do IO in stream processing arrows...
module ArrowStream where
-----------------------------------------------------------------------------
--
-- Definition of continuation based stream processor as an arrow
--
-- Reference: Magnus Carlsson, Thomas Hallgren, "Fudgets--Purely Functional
-- Processes with applications to Graphical User Interfaces",
-- Department of Computing Science, Chalmers University of
-- Technology, Goteborg University, Dissertation 1998
--
-- John Hughes, Generalising Monads to Arrows, November 10, 1998
--
-- History: 14-Aug-2002 Shawn Garbett, Creation
-- 01-Apr-2004 A
--
-------------------------------------------------------------------------------
import Char
import Control.Arrow
import Control.Concurrent
import Monad
import System.IO
data SP i o = Put o (SP i o)
| Get (i -> SP i o)
| Null
| DoIO (IO (SP i o))
instance Arrow SP where
arr f = Get (\x -> Put (f x) (arr f))
sp1 >>> Put c sp2 = Put c (sp1 >>> sp2)
Put b sp1 >>> Get f = sp1 >>> f b
Get f1 >>> Get f2 = Get (\a -> f1 a >>> Get f2)
_ >>> Null = Null
Null >>> Get _ = Null
-- Process io downstream first
sp >>> DoIO io = DoIO (Monad.liftM (sp >>>) io)
-- Process io upstream next
DoIO io >>> sp = DoIO (Monad.liftM (>>> sp) io)
first f = bypass [] f
where bypass ds (Get f) = Get (\(b,d) -> bypass (ds++[d]) (f b))
bypass (d:ds) (Put c sp) = Put (c,d) (bypass ds sp)
bypass [] (Put c sp) = Get (\(b,d) -> Put (c,d) (bypass [] sp))
-- making it up...
bypass ds (DoIO iosp) = DoIO (iosp >>= (\sp -> return (bypass ds sp)))
instance ArrowZero SP where
zeroArrow = Get (\x -> zeroArrow)
instance ArrowPlus SP where
Put b sp1 <+> sp2 = Put b (sp1 <+> sp2)
sp1 <+> Put b sp2 = Put b (sp1 <+> sp2)
Get f1 <+> Get f2 = Get (\a -> f1 a <+> f2 a)
sp1 <+> (DoIO ioSP) = DoIO (ioSP >>= (\sp2 -> return (sp1 <+> sp2)))
(DoIO ioSP) <+> sp2 = DoIO (ioSP >>= (\sp1 -> return (sp1 <+> sp2)))
sp1 <+> Null = sp1
Null <+> sp2 = sp2
instance ArrowChoice SP where
left (Put c sp) = Put (Left c) (left sp)
left (Get f) = Get (\z -> case z of
Left a -> left (f a)
Right b -> Put (Right b) (left (Get f)))
left (DoIO iosp) = DoIO (iosp >>= return . left)
-- | Run the IO in a DoIO
-- | the putStrLn's are just for debug...
spIO :: Show o => SP i o -> IO ()
spIO sp = case sp of
Null -> putStrLn "Null" >> return ()
Get _ -> putStrLn ("Get f") >> return ()
Put n sp' -> putStrLn ("Put " ++ (show n)) >> spIO sp'
DoIO io -> io >>= spIO
More information about the Haskell-Cafe
mailing list