{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Numeric.Probability.Object where
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Random as Rnd
import qualified Numeric.Probability.Shape as Shape
import qualified Numeric.Probability.Either as PE
import qualified Data.List as List
import Control.Monad (liftM, )
class Monad obj => C prob obj | obj -> prob where
fromFrequencies :: [(a,prob)] -> obj a
instance C Double Rnd.T where
fromFrequencies = Rnd.pick . Dist.fromFreqs
instance Fractional prob => C prob (Dist.T prob) where
fromFrequencies = Dist.fromFreqs
instance C prob obj => C prob (PE.EitherT b obj) where
fromFrequencies =
PE.EitherT . liftM Right . fromFrequencies
type Spread obj a = [a] -> obj a
shape :: (C prob obj, Fractional prob) =>
(prob -> prob) -> Spread obj a
shape _ [] = error "Probability.shape: empty list"
shape f xs =
let incr = 1 / fromIntegral (length xs - 1)
ps = List.map f (iterate (+incr) 0)
in fromFrequencies (zip xs ps)
linear :: (C prob obj, Fractional prob) => Spread obj a
linear = shape Shape.linear
uniform :: (C prob obj, Fractional prob) => Spread obj a
uniform = shape Shape.uniform
negExp :: (C prob obj, Floating prob) => Spread obj a
negExp = shape Shape.negExp
normal :: (C prob obj, Floating prob) => Spread obj a
normal = shape Shape.normal
enum :: (C prob obj, Floating prob) => [Int] -> Spread obj a
enum = relative . List.map fromIntegral
relative :: (C prob obj, Floating prob) => [prob] -> Spread obj a
relative ns = fromFrequencies . flip zip ns