> {-# LANGUAGE CPP, BangPatterns #-} > 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 (n-1) i' > where (x, i') = f ((), i) >