{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE Safe #-}
module Data.Generics.Is.Generic (
   -- * Predicates
   -- | Given a constructor @K@ for a type @T@ which implements 'Generic',
   --   and a value @a@ of type @T@, 'isC K a' evaluates @a@ to WHNF, and
   --   returns True if @K@ is the head constructor of the result.
   --
   --   prop> not . isC K ≡ isNotC K
   --   prop> $(is 'K) ≡ isC K
   is
  ,isNot
  ) where

import GHC.Generics
import Data.Generics.Is.Internal

is, isNot :: forall c a. (Constructs c a, Generic a, EqHead (Rep a)) => c -> a -> Bool
is c = eqH (from (construct c)) . from
isNot c = not . is c