{-# OPTIONS_GHC -fno-warn-noncanonical-monad-instances #-}

module Class140623 where

-- Example for full abstraction failure
t :: Bool -> (Bool -> Bool -> Bool) -> Bool
t b f = if (f True omega)
        then if (f omega True)
             then if (f False False) then omega else b
             else omega
        else omega
          where omega = omega

-- Let's reimplement the State-monad from scratch
-- Define a relevant type constructor 
newtype State s a = State {runState :: s -> (a, s)}

-- This is redundant for the example, but Haskell disallows
-- instances of Monad without being an instance of Functor
instance Functor (State s) where
    fmap f p = p >>= return . f

-- Same here
instance Applicative (State s) where
    pure = return
    f <*> p = f >>= \g-> p >>= return . g

-- Finally:
instance Monad (State s) where
    return x = State $ \s -> (x, s)
    (State t) >>= q = State $ \s -> let (x, s') = t s in (runState $ q x) s'


