{-# LANGUAGE InstanceSigs #-} module IOMaybe where import Control.Applicative newtype IOMaybe a = IOMaybe { runIOMaybe :: IO (Maybe a) } instance Functor IOMaybe where fmap :: (a -> b) -> IOMaybe a -> IOMaybe b fmap f a = IOMaybe $ do -- do in IO monad ma <- runIOMaybe a -- ma :: Maybe a return $ fmap f ma -- fmap in Maybe monad instance Applicative IOMaybe where pure :: a -> IOMaybe a pure = IOMaybe . return . Just (<*>) :: IOMaybe (a -> b) -> IOMaybe a -> IOMaybe b f <*> x = IOMaybe $ do mf <- runIOMaybe f -- mf :: Maybe (a -> b) mx <- runIOMaybe x -- mx :: Maybe a return $ mf <*> mx -- (<*>) in Maybe instance Monad IOMaybe where (>>=) :: IOMaybe a -> (a -> IOMaybe b) -> IOMaybe b x >>= f = IOMaybe $ do -- do in IO monad mx <- runIOMaybe x -- mx :: Maybe a case mx of Nothing -> return Nothing Just px -> runIOMaybe (f px) -- px :: a return = pure fail _ = IOMaybe (return Nothing) liftIOMaybe :: IO a -> IOMaybe a liftIOMaybe x = IOMaybe (Just <$> x)