Andrew Coppin andrewcoppin at btinternet.com
Sat Feb 20 05:30:10 EST 2010

```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,

(>==<) :: Property x y -> Property x y' -> Property x (y,y')
p0 >==< p1 = Property (p0,p1) (\x (q0,q1) -> (step x q0, step x 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?)

```