
The other day, I found myself writing the following code: data Property x y = forall s. Property s (x -> s -> s) (s -> y) step :: x -> Property x y -> Property x y step x (Property s f g) = Property (f x s) f g read :: Property x y -> y read (Property s _ g) = g s pure :: (x -> y) -> Property x y pure f = Property undefined const f fold :: (x -> y -> y) -> y -> Property x y fold f y = Property y f id fold1 :: (x -> x -> x) -> Property x x fold1 f = Property Nothing (\x mx -> maybe (Just x) (Just . f) mx) fromJust (>==>) :: Property x y -> Property y z -> Property x z p0 >==> p1 = Property (p0,p1) (\x (q0,q1) -> let w0 = step x q0 in (w0, step (read w0) q1)) (\(_,q1) -> (read q1)) (>==<) :: Property x y -> Property x y' -> Property x (y,y') p0 >==< p1 = Property (p0,p1) (\x (q0,q1) -> (step x q0, step x q1)) (\(q0,q1) -> (read q0, read q1)) sum = fold (+) 0 count = pure (const 1) >==> sum minimum = fold1 min maximum = fold1 max Have I just invented arrows? (And if so, why is the above code nowhere to be seen in the libraries?)