@@ -125,6 +125,10 @@ class SemiIsoApply f => SemiIsoAlternative f where
126 {-# MINIMAL siempty, (/|/) #-}
126 {-# MINIMAL siempty, (/|/) #-}
128+-- | An analogue of 'Monad' for 'SemiIsoFunctor'.
130+-- Because of the 'no throwing away' rule bind has to \"return\"
128class SemiIsoApply m => SemiIsoMonad m where
132class SemiIsoApply m => SemiIsoMonad m where
129 (//=) :: m a -> (a -> m b) -> m (a, b)
133 (//=) :: m a -> (a -> m b) -> m (a, b)
130 m //= f = swapped /$/ (f =// m)
134 m //= f = swapped /$/ (f =// m)
@@ -132,14 +136,20 @@ class SemiIsoApply m => SemiIsoMonad m where
132 (=//) :: (b -> m a) -> m b -> m (a, b)
136 (=//) :: (b -> m a) -> m b -> m (a, b)
133 f =// m = swapped /$/ (m //= f)
137 f =// m = swapped /$/ (m //= f)
139+ {-# MINIMAL (//=) | (=//) #-}
141+-- | A SemiIsoMonad with fixed point operator.
135class SemiIsoMonad m => SemiIsoFix m where
142class SemiIsoMonad m => SemiIsoFix m where
136 sifix :: (a -> m a) -> m a
143 sifix :: (a -> m a) -> m a
137 sifix f = dup /$/ (f =//= f)
144 sifix f = dup /$/ (f =//= f)
138 where dup = semiIso (\a -> Right (a, a)) (Right . fst)
145 where dup = semiIso (\a -> Right (a, a)) (Right . fst)
147+ -- | Fixed point combined with bind, it's so symmetric!
140 (=//=) :: (a -> m b) -> (b -> m a) -> m (a, b)
148 (=//=) :: (a -> m b) -> (b -> m a) -> m (a, b)
141 f =//= g = sifix (\(a, b) -> g b /*/ f a)
149 f =//= g = sifix (\(a, b) -> g b /*/ f a)
151+ {-# MINIMAL sifix | (=//=) #-}
143-- | Equivalent of 'sequence'.
153-- | Equivalent of 'sequence'.
145-- Note that it is not possible to write sequence_, because
155-- Note that it is not possible to write sequence_, because