module ST where type ST s a = s -> (a, s) unitST :: a -> ST s a unitST a = \ s -> (a, s) bindST :: ST s a -> (a -> ST s b) -> ST s b m `bindST` k = \ s0 -> let { (a, s1) = m s0 } in k a s1 type Pos s a = s -> (a, a -> s) p2_1 :: Pos (x, y) x p2_1 = \ (x, y) -> (x, \ x1 -> (x1, y)) xP = p2_1 p2_2 :: Pos (x, y) y p2_2 = \ (x, y) -> (y, \ y1 -> (x, y1)) yP = p2_2 p3_1 :: Pos (x, y, z) x p3_1 = \ (x, y, z) -> (x, \ x1 -> (x1, y, z)) xT = p3_1 p3_2 :: Pos (x, y, z) y p3_2 = \ (x, y, z) -> (y, \ y1 -> (x, y1, z)) yT = p3_2 p3_3 :: Pos (x, y, z) z p3_3 = \ (x, y, z) -> (z, \ z1 -> (x, y, z1)) zT = p3_3 getST :: Pos s a -> ST s a getST p = \ s -> (fst (p s), s) setST :: Pos s a -> a -> ST s () setST p v = \ s -> ((), snd (p s) v)