    {-# LANGUAGE MultiParamTypeClasses
               , FlexibleInstances
               , UndecidableInstances
               , DeriveDataTypeable
               #-}

    module Numeric.Coalgebra.Incidence
      ( Interval'(..)
      , zeta'
      , moebius'
      ) where

    import Data.Data
    import Numeric.Algebra.Class
    import Numeric.Algebra.Unital
    import Numeric.Algebra.Commutative
    import Numeric.Ring.Class
    import Numeric.Order.LocallyFinite

    -- | the dual incidence algebra basis
    data Interval' a = Interval' a a deriving (Eq,Ord,Show,Read,Data,Typeable)

    instance (Eq a, Commutative r, Monoidal r, Semiring r) => Coalgebra r (Interval' a) where
      comult f (Interval' a b) (Interval' b' c)
        | b == b' = f (Interval' a c)
        | otherwise = zero

    instance (Eq a, Bounded a, Commutative r, Monoidal r, Semiring r) => CounitalCoalgebra r (Interval' a) where
      counit f = f (Interval' minBound maxBound)

    zeta' :: Unital r => Interval' a -> r
    zeta' = const one

    moebius' :: (Ring r, LocallyFiniteOrder a) => Interval' a -> r
    moebius' (Interval' a b) = moebiusInversion a b