module Suspend where import Finite import Pretty import Text.PrettyPrint import Monad (liftM, mapM) -- There are three individuals in the domain: Alice, Bob, and Carol. -- For brevity, we abbreviate them to their initials, especially in the handout. data E = A | B | C deriving (Eq, Ord, Enum, Bounded, Show, Read) instance Finite E where everything = enumEverything cardinality = enumCardinality instance Pretty E data Suspend a = Done a | Ask (E -> Suspend a) deriving (Eq, Ord, Show) instance (Pretty a) => Pretty (Suspend a) where pretty (Done a) = text "Done" <+> pretty a pretty (Ask f ) = text "Ask" <+> pretty f instance Monad Suspend where return a = Done a Done a >>= k = k a Ask f >>= k = Ask (\e -> f e >>= k) ask :: Suspend E ask = Ask Done data Quantify w a = Quantify ((a -> w) -> w) instance Monad (Quantify w) where return a = Quantify (\c -> c a) Quantify m >>= k = Quantify (\c -> m (\a -> case k a of Quantify n -> n c)) everyone :: Quantify Bool E everyone = Quantify (\c -> and (map c everything)) eval :: Quantify w w -> w eval (Quantify m) = m id data QuantifyT w m a = QuantifyT ((a -> m w) -> m w) instance Monad (QuantifyT w m) where return a = QuantifyT (\c -> c a) QuantifyT m >>= k = QuantifyT (\c -> m (\a -> case k a of QuantifyT n -> n c)) class MonadT t where lift :: (Monad m) => m a -> t m a instance MonadT (QuantifyT w) where lift m = QuantifyT (\c -> m >>= c) everyoneT :: (Monad m) => QuantifyT Bool m E everyoneT = QuantifyT (\c -> liftM and (mapM c everything)) evalT :: (Monad m) => QuantifyT w m w -> m w evalT (QuantifyT m) = m return