>
> module Control.SF.SF where
#if __GLASGOW_HASKELL__ >= 610
> import Control.Category
> import Prelude hiding ((.), id)
#endif
> import Control.Arrow
> import Control.Arrow.ArrowP
> import Control.Arrow.Operations
> newtype SF a b = SF { runSF :: (a -> (b, SF a b)) }
#if __GLASGOW_HASKELL__ >= 610
> instance Category SF where
> id = SF h where h x = (x, SF h)
> g . f = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f x
> (z, g') = runSF g y
> in f' `seq` g' `seq` (z, SF (h f' g'))
> instance Arrow SF where
> arr f = g
> where g = SF (\x -> (f x, g))
> first f = SF (g f)
> where
> g f (x, z) = f' `seq` ((y, z), SF (g f'))
> where (y, f') = runSF f x
> f &&& g = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f x
> (z, g') = runSF g x
> in ((y, z), SF (h f' g'))
> f *** g = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f (fst x)
> (z, g') = runSF g (snd x)
> in ((y, z), SF (h f' g'))
#else
> instance Arrow SF where
> arr f = g
> where g = SF (\x -> (f x, g))
> f >>> g = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f x
> (z, g') = runSF g y
> in (z, SF (h f' g'))
> first f = SF (g f)
> where
> g f (x, z) = ((y, z), SF (g f'))
> where (y, f') = runSF f x
> f &&& g = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f x
> (z, g') = runSF g x
> in ((y, z), SF (h f' g'))
> f *** g = SF (h f g)
> where
> h f g x =
> let (y, f') = runSF f (fst x)
> (z, g') = runSF g (snd x)
> in ((y, z), SF (h f' g'))
#endif
> instance ArrowLoop SF where
> loop sf = SF (g sf)
> where
> g f x = f' `seq` (y, SF (g f'))
> where ((y, z), f') = runSF f (x, z)
> instance ArrowChoice SF where
> left sf = SF (g sf)
> where
> g f x = case x of
> Left a -> let (y, f') = runSF f a in f' `seq` (Left y, SF (g f'))
> Right b -> (Right b, SF (g f))
>
> instance ArrowCircuit SF where
> delay i = SF (f i)
> where f i x = (i, SF (f x))
> run :: SF a b -> [a] -> [b]
> run _ [] = []
> run (SF f) (x:xs) =
> let (y, f') = f x
> in y `seq` f' `seq` (y : run f' xs)
>
> unfold :: SF () a -> [a]
> unfold = flip run inp
> where inp = () : inp
>
>
> nth :: Int -> SF () a -> a
> nth n (SF f) = x `seq` if n == 0 then x else nth (n 1) f'
> where (x, f') = f ()
>
> nth' :: Int -> (b, ((), b) -> (a, b)) -> a
> nth' !n (i, f) = n `seq` i `seq` f `seq` aux n i
> where
> aux !n !i = x `seq` i' `seq` if n == 0 then x else aux (n1) i'
> where (x, i') = f ((), i)
>