import Control.Applicative
import Data.Time.Clock.POSIX (getPOSIXTime)
data MyCoolIO a = MCIO (IO a)
instance Functor MyCoolIO where
fmap f (MCIO xIO) = MCIO $ fmap f xIO
instance Applicative MyCoolIO where
pure = MCIO . pure
(MCIO fIO) <*> (MCIO xIO) = MCIO $ fIO <*> xIO
instance Monad MyCoolIO where
return = pure
(MCIO xIO) >>= f = MCIO $ xIO >>= \x -> (let (MCIO r) = f x in r)
(MCIO xIO) >> (MCIO yIO) = MCIO $ do
now <- getPOSIXTime
if even (round now) then xIO >> yIO
else yIO >>= \y -> (xIO >> return y)
myPutStrLn :: String -> MyCoolIO ()
myPutStrLn s = MCIO $ putStrLn s
myMain :: MyCoolIO () -> IO ()
myMain (MCIO io) = io
main = myMain $ do
myPutStrLn "first"
myPutStrLn "second"
myPutStrLn "third"