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

    module Numeric.Algebra.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.Class
    import Numeric.Order.LocallyFinite

    -- the basis for an incidence algebra
    data Interval a = Interval a a deriving (Eq,Ord,Show,Read,Data,Typeable)

    instance (Commutative r, Monoidal r, Semiring r, LocallyFiniteOrder a) => Algebra r (Interval a) where
      mult f (Interval a c) = sumWith (\b -> f (Interval a b) (Interval b c)) $ range a c

    instance (Commutative r, Monoidal r, Semiring r, LocallyFiniteOrder a) => UnitalAlgebra r (Interval a) where
      unit r (Interval a b)
        | a ~~ b = r
        | otherwise = zero

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

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