Created
June 12, 2021 06:35
-
-
Save dmwit/f9dbbbfc37ef5e5ab812d860eed77708 to your computer and use it in GitHub Desktop.
MonadLogic, but both associations of >>- are productive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DeriveFunctor #-} | |
{-# LANGUAGE DeriveTraversable #-} | |
import Control.Applicative | |
import Control.Monad | |
import Data.Maybe | |
-- explicit failure | |
newtype EF a = EF { unEF :: [Maybe a] } | |
deriving (Eq, Ord, Read, Show, Functor, Foldable, Traversable) | |
instance Applicative EF where | |
pure = EF . pure . pure | |
(<*>) = ap | |
instance Monad EF where | |
EF xms >>= f = EF | |
[ fxm | |
| xm <- xms | |
, fxm <- case xm of | |
Nothing -> [Nothing] | |
Just x -> unEF (f x) | |
] | |
instance Alternative EF where | |
empty = EF [Nothing] | |
EF xms <|> EF xms' = EF (xms <|> xms') | |
runEF :: EF a -> [a] | |
runEF = catMaybes . unEF | |
interleave :: EF a -> EF a -> EF a | |
interleave (EF []) m2 = m2 | |
interleave (EF (xm:m1)) m2 = EF (xm : unEF (interleave m2 (EF m1))) | |
infixl 1 >>- | |
(>>-) :: EF a -> (a -> EF b) -> EF b | |
EF [] >>- f = EF [] | |
EF (xm:xms) >>- f = maybe | |
(EF . (Nothing:) . unEF) | |
(interleave . f) | |
xm | |
(EF xms >>- f) | |
odds :: EF Integer | |
odds = pure 1 <|> fmap (2+) odds | |
oddsPlus :: Integer -> EF Integer | |
oddsPlus n = odds >>= \a -> pure (a+n) | |
ensure :: Alternative f => (a -> Bool) -> a -> f a | |
ensure p x = x <$ guard (p x) | |
leftAssociated :: [Integer] | |
leftAssociated = runEF ((pure 0 <|> pure 1) >>- oddsPlus >>- ensure even) | |
rightAssociated :: [Integer] | |
rightAssociated = runEF ((pure 0 <|> pure 1) >>- (\a -> oddsPlus a >>- ensure even)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment