module Boolean.FuzzyBool where


import Boolean.Algebra
import Ratio


type Fuzzy = Fuzz Rational

newtype Fuzz a = Fuzz { fromFuzz :: a }
    deriving(Ord,Eq,Enum,Bounded,Show,Read)


instance Ord a => SemiBooleanAlgebra (Fuzz a) where
    a && b = min a b
    a || b = max a b

instance (Ord a, Num a) => BooleanAlgebra (Fuzz a) where
    true = Fuzz 1
    false = Fuzz 0
    not (Fuzz x) = Fuzz (1 - x)
    and xs = minimum (true:xs)
    or xs = maximum (false:xs)


avg (Fuzz a) (Fuzz b) = (a + b) / 2
average [] = error "average of empty list"   -- should this degenerate into something
average xs = f xs 0 0 where
    f [] n m = Fuzz (n / m)
    f (Fuzz x:xs) n m = a `seq` b `seq` f xs a b   where
        a = n + x
        b = m + 1
