-- | Functor laws
-- 
-- > fmap id = id
-- > fmap f . fmap g = fmap (f . g)
module Test.QuickCheck.Property.Functor (
    module Test.QuickCheck.Property.Common
  , prop_FunctorId
  , prop_FunctorCompose
  ) where

import Test.QuickCheck.Property.Common
import Test.QuickCheck.Property.Common.Internal

-- | @fmap id = id@
prop_FunctorId :: Functor f => T (f a) -> f a -> Equal (f a)
prop_FunctorId T f = f .==. fmap id f

-- | It's not possible to generate arbitrary functions. Therefore they
--   are passed as arguments. 
prop_FunctorCompose :: Functor f => 
                       (a -> b) -- ^ f
                    -> (b -> c) -- ^ g
                    -> T (f a)
                    -> f a
                    -> Equal (f c)
prop_FunctorCompose f g T x = (fmap g $ fmap f $ x) .==. (fmap (g . f) x)