packages feed

heyting-algebras-0.2.0.1: src/Algebra/Boolean.hs

{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Algebra.Boolean
  ( BooleanAlgebra
  , (==>)
  , neg
    -- * Adjunction between Boolean and Heyting algebras
  , Boolean
  , runBooleanAlgebra
  , boolean
  ) where

import           Control.Applicative    (Const (..))
import           Data.Data              (Data, Typeable)
import           Data.Functor.Identity  (Identity (..))
import           Data.Proxy             (Proxy (..))
import           Data.Semigroup         ( All (..)
                                        , Any (..)
                                        , Endo (..)
                                        )
import           Data.Tagged            (Tagged (..))
import           GHC.Generics           (Generic)

import           Algebra.Heyting
import           Algebra.Lattice        ( Lattice
                                        , BoundedJoinSemiLattice
                                        , BoundedMeetSemiLattice
                                        )

class Heyting a => Boolean a

instance Boolean Bool

instance Boolean All

instance Boolean Any

instance Boolean ()

instance Boolean (Proxy a)

instance Boolean a => Boolean (Tagged t a)

instance Boolean b => Boolean (a -> b)

#if MIN_VERSION_base(4,8,0)
instance Boolean a => Boolean (Identity a)
#endif

instance Boolean a => Boolean (Const a b)

instance Boolean a => Boolean (Endo a)

-- | Every Heyting algebra contains a Boolean algebra. @'toBoolean'@ maps onto
-- it; moreover it is a monad (Heyting algebra is a category as every poset is)
-- which preserves finite infima.
--
toBoolean :: Heyting a => a -> a
toBoolean = neg . neg

-- |
-- @'Boolean'@ is the left adjoint functor from the category of Heyting algebras
-- to the category of Boolean algebras; its right adjoint is the inclusion.
newtype BooleanAlgebra a = BooleanAlgebra
    { runBooleanAlgebra :: a -- ^ extract value from @'Boolean'@
    }
  deriving
    ( BoundedJoinSemiLattice
    , BoundedMeetSemiLattice
    , Lattice
    , Heyting
    , Eq, Ord, Read, Show, Bounded, Typeable, Data, Generic
    )

instance Heyting a => Boolean (BooleanAlgebra a)

-- |
-- Smart constructro of the @'Boolean'@ type.
boolean :: Heyting a => a -> BooleanAlgebra a
boolean = BooleanAlgebra . toBoolean