import Prelude hiding (const, id, (.)) import Control.Category data St a b = St (a -> (b, St a b)) ap :: St a b -> [a] -> [b] ap _ [] = [] ap (St f) (a:as) = let (b, nSt) = f a in b : ap nSt as const :: a -> St b a const x = St $ \_ -> (x, const x) integral :: Num a => St a a integral = from 0 where from n = St $ \x -> st x where st x = let s = x + n in (s, from s) instance Category St where -- id :: St a a id = St $ (\x -> (x, id)) -- (.) :: St b c -> St a b -> St a c (.) (St f) (St g) = St $ \x -> compose x where compose x = (x2, f1 . g1) where (x1, g1) = g x (x2, f1) = f x1 main = do print $ ap (integral . id) [0,1,2] == ap (id . integral) [0,1,2] print $ ap (integral . (const 42 . integral)) [0,1,2] == ap ((integral . const 42) . integral) [0,1,2] print $ ap (const 42) [0,1,2] == [42,42,42] print $ ap integral [0,1,2,3] == [0,1,3,6]