qed-0.0: test/Classes.hs
module Classes(classes) where
import Proof.QED
import Control.Monad
classes = do
lawsMonoid <- laws $ do
law "a => a <> mempty = a"
law "a => mempty <> a = a"
law "a b c => a <> (b <> c) = (a <> b) <> c"
lawsFunctor <- laws $ do
law "fmap id = id"
law "f g => fmap f . fmap g = fmap (f . g)"
lawsApplicative <- laws $ do
law "v => pure id <*> v = v"
law "u v w => pure (.) <*> u <*> v <*> w = u <*> (v <*> w)"
law "f x => pure f <*> pure x = pure (f x)"
law "u y => u <*> pure y = pure ($ y) <*> u"
lawsMonad <- laws $ do
law "a k => return a >>= k = k a"
law "m => m >>= return = m"
law "m k h => m >>= (\\x -> k x >>= h) = (m >>= k) >>= h"
prove "x => [] ++ x = x" $ do
unfold "++"
prove "x => x ++ [] = x" $ do
recurse
rhs $ strict "[]"
prove "x y z => (x ++ y) ++ z = x ++ (y ++ z)" $ do
recurse
bhs $ unfold "++"
satisfy "Monoid []" lawsMonoid $ do
bind "mempty = []"
bind "(<>) = (++)"
prove "map id = id" $ do
bhs $ unfold "id"
expand
recurse
rhs $ strict "[]"
prove "f g => map f . map g = map (f . g)" $ do
twice $ unfold "."
twice unlet
rhs expand
recurse
unfold "map"
satisfy "Functor []" lawsFunctor $ do
bind "fmap = map"
decl "return_List = (:[])"
decl "bind_List = flip concatMap"
let unwind = mapM_ (perhaps . many . unfold) ["return_List","bind_List","concatMap","concat","flip","."]
when False $ prove "a k => return_List a `bind_List` k = k a" $ do
unwind
unfold "map"
unfold "foldr"
unfold "foldr"
unfold "map"
prove "m => m `bind_List` return_List = m" $ do
unwind
recurse
unfold "map"
rhs $ strict "[]"
twice $ unfold "++"
prove "m k h => m `bind_List` (\\x -> k x `bind_List` h) = (m `bind_List` k) `bind_List` h" $ do
unwind
divide
recurse
rhs $ unfold "foldr"
rhs $ unfold "map"
rhs $ unfold "++"
unsafeCheat "bored"
skip $ satisfy "Monad []" lawsMonad $ do
bind "return = return_List"
bind "(>>=) = bind_List"
prove "v => return id `ap` v = v" $ do
unfold "ap"
unfold "liftM2"
unfold "$"
unsafeCheat "need laws"
{-
-- (>>=) (return id) (\ b -> (>>=) a (\ c -> return (b c))) = a
-- return a >>= k = k a"
-- (>>=) a (\ c -> return c)) = a
-- a = a
data Monad a = Return a | forall x . Bind (Monad x) (x -> Monad a)
eval (Return a) = a
eval (Bind (Return a) f) = f a
eval
-}
skip $ prove "u v w => return (.) `ap` u `ap` v `ap` w = u `ap` (v `ap` w)" $ do
replicateM_ 100 unfold_
skip $ prove "f x => return f `ap` return x = return (f x)" $ do
unfold "ap"
unfold "liftM2"
unfold "$"
unlet
return ()
skip $ do
prove "u y => u `ap` return y = return ($ y) `ap` u" $ do
return ()
lawsMonad <- laws $ do
law "a k => return a >>= k = k a"
law "m => m >>= return = m"
law "m k h => m >>= (\\x -> k x >>= h) = (m >>= k) >>= h"
satisfy "Applicative Monad" lawsApplicative $ do
bind "pure = return"
bind "(<*>) = ap"