histogram-fill (empty) → 0.1.0
raw patch · 8 files changed
+723/−0 lines, 8 filesdep +basedep +uvectorsetup-changed
Dependencies added: base, uvector
Files
- Data/Histogram.hs +129/−0
- Data/Histogram/Bin.hs +162/−0
- Data/Histogram/Fill.hs +188/−0
- Data/Histogram/Parse.hs +46/−0
- Data/Histogram/ST.hs +170/−0
- LICENSE +0/−0
- Setup.hs +2/−0
- histogram-fill.cabal +26/−0
+ Data/Histogram.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeOperators #-}+-- |+-- Module : Data.Histogram+-- Copyright : Copyright (c) 2009, Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- License : BSD3+-- Maintainer : Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- Stability : experimental+-- +-- Immutable histograms. ++module Data.Histogram ( -- * Immutable histogram+ Histogram(..)+ , module Data.Histogram.Bin+ , mapHist+ , histBin+ , histData+ , underflows+ , overflows+ , outOfRange+ , readHistogram+ -- * Conversion+ , asList+ , asPairVector+ , asVectorPairs+ -- * Slicing+ , sliceY+ , sliceX+ ) where++import Control.Arrow ((***))+import Control.Monad (ap)+import Data.Array.Vector+import Text.Read+import Text.ParserCombinators.ReadPrec (readPrec_to_S)++import Data.Histogram.Bin+import Data.Histogram.Parse+++-- | Immutable histogram. Histogram consists of binning algorithm,+-- optional number of under and overflows, and data. +data Histogram bin a where+ Histogram :: (Bin bin, UA a) => + bin+ -> Maybe (a,a)+ -> UArr a+ -> Histogram bin a+++instance (Show a, Show (BinValue bin), Show bin) => Show (Histogram bin a) where+ show h@(Histogram bin uo _) = "# Histogram\n" ++ showUO uo ++ show bin +++ (unlines $ map showT $ asList h)+ where+ showT (x,y) = show x ++ "\t" ++ show y+ showUO (Just (u,o)) = "# Underflows = " ++ show u ++ "\n" +++ "# Overflows = " ++ show o ++ "\n"+ showUO Nothing = "# Underflows = \n" +++ "# Overflows = \n"++histHeader :: (Read bin, Read a, Bin bin, UA a) => ReadPrec (UArr a -> Histogram bin a)+histHeader = do+ keyword "Histogram"+ u <- maybeValue "Underflows"+ o <- maybeValue "Overflows"+ bin <- readPrec+ return $ Histogram bin ((,) `fmap` u `ap` o)++-- | Convert String to histogram. Histogram do not have Read instance+-- because of slowness of ReadP+readHistogram :: (Read bin, Read a, Bin bin, UA a) => String -> Histogram bin a+readHistogram str = + let [(h,rest)] = readPrec_to_S histHeader 0 str + xs = map last . filter (not . null) . map words . lines $ rest+ in h (toU $ map read xs)++-- | fmap lookalike. It's not possible to create Functor instance+-- because of UA restriction.+mapHist :: UA b => (a -> b) -> Histogram bin a -> Histogram bin b+mapHist f (Histogram bin uo a) = Histogram bin (fmap (f *** f) uo) (mapU f a)++-- | Histogram bins+histBin :: Histogram bin a -> bin+histBin (Histogram bin _ _) = bin++-- | Histogram data as vector+histData :: Histogram bin a -> UArr a+histData (Histogram _ _ a) = a++-- | Number of underflows+underflows :: Histogram bin a -> Maybe a+underflows (Histogram _ uo _) = fmap fst uo++-- | Number of overflows+overflows :: Histogram bin a -> Maybe a+overflows (Histogram _ uo _) = fmap snd uo++-- | Underflows and overflows+outOfRange :: Histogram bin a -> Maybe (a,a)+outOfRange (Histogram _ uo _) = uo++-- | Convert histogram to list.+asList :: Histogram bin a -> [(BinValue bin, a)]+asList (Histogram bin _ arr) = map (fromIndex bin) [0..] `zip` fromU arr++-- | Convert to pair of vectors+asPairVector :: UA (BinValue bin) => Histogram bin a -> (UArr (BinValue bin), UArr a)+asPairVector (Histogram bin _ a) = (toU $ map (fromIndex bin) [0 .. nBins bin], a)++-- | Convert to vector of pairs+asVectorPairs :: UA (BinValue bin) => Histogram bin a -> UArr ((BinValue bin) :*: a)+asVectorPairs h@(Histogram _ _ _) = uncurry zipU . asPairVector $ h++-- | Slice 2D histogram along Y axis. This function is fast because it does not require reallocations.+sliceY :: (Bin bX, Bin bY) => Histogram (Bin2D bX bY) a -> [(BinValue bY, Histogram bX a)]+sliceY (Histogram b@(Bin2D bX _) _ a) = map mkHist $ init [0, nBins bX .. nBins b]+ where+ mkHist i = ( snd $ fromIndex b i+ , Histogram bX Nothing (sliceU a i (nBins bX)) )++-- | Slice 2D histogram along X axis.+sliceX :: (Bin bX, Bin bY) => Histogram (Bin2D bX bY) a -> [(BinValue bX, Histogram bY a)]+sliceX (Histogram b@(Bin2D bX bY) _ a) = map mkHist $ init [0 .. nx]+ where+ nx = nBins bX+ n = nBins b+ mkHist i = ( fst $ fromIndex b i+ , Histogram bY Nothing (toU $ map (indexU a) [i,i+nx .. n-1]) )
+ Data/Histogram/Bin.hs view
@@ -0,0 +1,162 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE BangPatterns #-}+-- |+-- Module : Data.Histogram.Bin+-- Copyright : Copyright (c) 2009, Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- License : BSD3+-- Maintainer : Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- Stability : experimental+-- +-- Binning algorithms. This is mapping from set of interest to integer+-- indices and approximate reverse. ++module Data.Histogram.Bin ( -- * Type class+ Bin(..)+ -- * Integer bins+ , BinI(..)+ -- * Floating point bins+ , BinF+ , binF+ , binFn+ -- * 2D bins+ , Bin2D(..)+ , (><)+ ) where++import Data.Histogram.Parse+import Text.Read (Read(..))++++-- | Abstract binning algorithm. Following invariant is expected to hold: +-- +-- > toIndex . fromIndex == id+-- +-- Reverse is not nessearily true. +class Bin b where+ -- | Type of value to bin+ type BinValue b+ -- | Convert from value to index. No bound checking performed+ toIndex :: b -> BinValue b -> Int+ {-# INLINE toIndex #-}+ -- | Convert from index to value. + fromIndex :: b -> Int -> BinValue b + -- | Total number of bins+ nBins :: b -> Int+++----------------------------------------------------------------+-- Integer bin++-- | Integer bins. This is inclusive interval [from,to]+data BinI = BinI !Int !Int++instance Bin BinI where+ type BinValue BinI = Int+ toIndex !(BinI base _) !x = x - base+ fromIndex !(BinI base _) !x = x + base+ nBins !(BinI x y) = y - x + 1++instance Show BinI where+ show (BinI lo hi) = unlines [ "# BinI"+ , "# Low = " ++ show lo+ , "# High = " ++ show hi+ ]++instance Read BinI where+ readPrec = do+ keyword "BinI"+ l <- value "Low"+ h <- value "High"+ return $ BinI l h+++----------------------------------------------------------------+-- Floating point bin++-- | Floaintg point bins with equal sizes.+data BinF f where+ BinF :: RealFrac f => !f -> !f -> !Int -> BinF f ++-- | Create bins +binF :: RealFrac f => + f -- ^ Lower bound of range+ -> Int -- ^ Number of bins+ -> f -- ^ Upper bound of range+ -> BinF f+binF from n to = BinF from ((to - from) / fromIntegral n) n++-- | Create bins. Note that actual upper bound can differ from specified.+binFn :: RealFrac f =>+ f -- ^ Begin of range+ -> f -- ^ Size of step+ -> f -- ^ Approximation of end of range+ -> BinF f +binFn from step to = BinF from step (round $ (to - from) / step)++instance Bin (BinF f) where+ type BinValue (BinF f) = f + toIndex !(BinF from step _) !x = floor $ (x-from) / step+ fromIndex !(BinF from step _) !i = (step/2) + (fromIntegral i * step) + from + nBins !(BinF _ _ n) = n+ {-# SPECIALIZE instance Bin (BinF Double) #-}+ {-# SPECIALIZE instance Bin (BinF Float) #-}++instance Show f => Show (BinF f) where+ show (BinF base step n) = unlines [ "# BinF"+ , "# Base = " ++ show base+ , "# Step = " ++ show step+ , "# N = " ++ show n+ ]++instance (Read f, RealFrac f) => Read (BinF f) where+ readPrec = do+ keyword "BinF"+ base <- value "Base"+ step <- value "Step"+ n <- value "N"+ return $ BinF base step n+++----------------------------------------------------------------+-- 2D bin++-- | 2D bins. bin1 is binning along X axis and bin2 is one along Y axis. +data Bin2D bin1 bin2 = Bin2D bin1 bin2++-- | Alias for 'Bin2D'.+(><) :: bin1 -> bin2 -> Bin2D bin1 bin2+(><) = Bin2D++instance (Bin bin1, Bin bin2) => Bin (Bin2D bin1 bin2) where+ type BinValue (Bin2D bin1 bin2) = (BinValue bin1, BinValue bin2)++ toIndex (Bin2D bx by) (x,y) + | ix < 0 || ix >= rx || iy < 0 || iy >= ry = maxBound+ | otherwise = ix + iy*rx+ where+ ix = toIndex bx x+ iy = toIndex by y+ rx = nBins bx+ ry = nBins by++ fromIndex (Bin2D bx by) i = let (iy,ix) = divMod i (nBins bx)+ in (fromIndex bx ix, fromIndex by iy)++ nBins (Bin2D b1 b2) = (nBins b1) * (nBins b2)++instance (Show b1, Show b2) => Show (Bin2D b1 b2) where+ show (Bin2D b1 b2) = "# Bin2D\n" +++ "# X\n" ++ + show b1 +++ "# Y\n" +++ show b2+instance (Read b1, Read b2) => Read (Bin2D b1 b2) where+ readPrec = do+ keyword "Bin2D"+ keyword "X"+ b1 <- readPrec+ keyword "Y"+ b2 <- readPrec+ return $ Bin2D b1 b2
+ Data/Histogram/Fill.hs view
@@ -0,0 +1,188 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Rank2Types #-}+-- |+-- Module : Data.Histogram.Fill+-- Copyright : Copyright (c) 2009, Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- License : BSD3+-- Maintainer : Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- Stability : experimental+-- +-- Module with algorithms for histogram filling. This is pure wrapper+-- around stateful histograms.+-- +module Data.Histogram.Fill ( -- * Type classes & wrappers+ HBuilderCl(..)+ , HBuilder+ , builderList+ , builderListWrap++ -- * Fill routines+ , createHistograms++ -- * Histogram constructors + , module Data.Histogram.Bin+ , mkHist+ , mkHist1+ , mkHistWgh+ , mkHistWgh1+ , mkHistMonoid+ , mkHistMonoid1+ , forceInt+ , forceDouble+ , forceFloat+ -- * Internals+ , HistBuilder+ ) where++import Control.Monad.ST (ST)+import Data.Monoid (Monoid, mempty)++import Data.Array.Vector+import Data.Histogram+import Data.Histogram.Bin+import Data.Histogram.ST++----------------------------------------------------------------++-- | Create and fill histogram(s).+createHistograms :: Monoid b =>+ HBuilder a b -- ^ Instructions how to fill histograms+ -> [a] -- ^ List of data to fill histogram with+ -> b -- ^ Result+createHistograms h xs = fillHistograms (runBuilder h) xs++----------------------------------------------------------------++-- | Histogram builder typeclass. Instance of this class contain+-- instructions how to build histograms.+class HBuilderCl h where + -- | Convert input type of histogram from a to a'+ modifyIn :: (a' -> a) -> h a b -> h a' b + -- | Convert output of histogram + modifyOut :: (b -> b') -> h a b -> h a b'+ -- | Create stateful histogram from instructions. Histograms could+ -- be filled either in the ST monad or with createHistograms+ runBuilder :: h a b -> ST s (Accum s a b)+++----------------------------------------------------------------++-- | Abstract histogram builder. All real builders should be wrapper+-- in this type+data HBuilder a b where+ MkHBuilder :: HBuilderCl h => h a b -> HBuilder a b++instance HBuilderCl HBuilder where + modifyIn f (MkHBuilder h) = MkHBuilder $ modifyIn f h+ modifyOut g (MkHBuilder h) = MkHBuilder $ modifyOut g h + runBuilder (MkHBuilder h) = runBuilder h+++----------------------------------------------------------------++-- List of histograms. +newtype HBuilderList a b = HBuilderList [HBuilder a b]++-- | Wrap list of histogram builders into HBuilder.+builderList :: [HBuilder a b] -> HBuilder a [b]+builderList = MkHBuilder . modifyOut (:[]) . HBuilderList++-- | Wrap list of histogram builders into HBuilder and do not change return type.+builderListWrap :: [HBuilder a b] -> HBuilder a b+builderListWrap = MkHBuilder . HBuilderList++instance HBuilderCl HBuilderList where+ modifyIn f (HBuilderList l) = HBuilderList $ map (modifyIn f) l+ modifyOut g (HBuilderList l) = HBuilderList $ map (modifyOut g) l+ runBuilder (HBuilderList l) = accumList $ map runBuilder l++----------------------------------------------------------------++-- | Generic histogram builder. +data HistBuilder a b where+ HistBuilder :: (Bin bin, UA val) =>+ bin -- Bin type+ -> val -- Zero element+ -> (forall s . a -> HistogramST s bin val -> ST s ()) -- Input function+ -> (Histogram bin val -> b) -- Output function+ -> HistBuilder a b++instance HBuilderCl HistBuilder where+ modifyIn f (HistBuilder bin z inp out) = HistBuilder bin z (inp . f) out+ modifyOut g (HistBuilder bin z inp out) = HistBuilder bin z inp (g . out)+ runBuilder (HistBuilder bin z inp out) = accumHist inp out =<< newHistogramST z bin++++----------------------------------------------------------------+-- Histogram constructors +----------------------------------------------------------------++-- | Function used to restrict type of histrogram.+forceInt :: Histogram bin Int -> Histogram bin Int+forceInt = id++-- | Function used to restrict type of histrogram.+forceDouble :: Histogram bin Double -> Histogram bin Double+forceDouble = id++-- | Function used to restrict type of histrogram.+forceFloat :: Histogram bin Float -> Histogram bin Float+forceFloat = id++-- | Create histogram builder which take single item as input. Each+-- item has weight 1. To set type of bin 'force*' function could be used.+mkHist1 :: (Bin bin, UA val, Num val) =>+ bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function + -> (a -> BinValue bin) -- ^ Input function+ -> HBuilder a b+mkHist1 bin out inp = MkHBuilder $ HistBuilder bin 0 (flip fillOne . inp) out++-- | Create histogram builder which take many items as input. Each+-- item has weight 1. To set type of bin 'force*' function could be+-- used.+mkHist :: (Bin bin, UA val, Num val) =>+ bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function+ -> (a -> [BinValue bin]) -- ^ Input function + -> HBuilder a b+mkHist bin out inp = MkHBuilder $ HistBuilder bin 0 fill out+ where+ fill a h = mapM_ (fillOne h) $ inp a++-- | Create histogram with weighted bin. Takes one item at time. +mkHistWgh1 :: (Bin bin, UA val, Num val) =>+ bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function+ -> (a -> (BinValue bin, val)) -- ^ Input function+ -> HBuilder a b+mkHistWgh1 bin out inp = MkHBuilder $ HistBuilder bin 0 (flip fillOneW . inp) out++-- | Create histogram with weighted bin. Takes many items at time.+mkHistWgh :: (Bin bin, UA val, Num val) => + bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function+ -> (a -> [(BinValue bin, val)]) -- ^ Input function+ -> HBuilder a b+mkHistWgh bin out inp = MkHBuilder $ HistBuilder bin 0 fill out+ where+ fill a h = mapM_ (fillOneW h) $ inp a++-- | Create histogram with monoidal bins+mkHistMonoid1 :: (Bin bin, UA val, Monoid val) =>+ bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function+ -> (a -> (BinValue bin, val)) -- ^ Input function+ -> HBuilder a b+mkHistMonoid1 bin out inp = MkHBuilder $ HistBuilder bin mempty (flip fillMonoid . inp) out++-- | Create histogram with monoidal bins. Takes many items at time.+mkHistMonoid :: (Bin bin, UA val, Monoid val) =>+ bin -- ^ Bin information+ -> (Histogram bin val -> b) -- ^ Output function+ -> (a -> [(BinValue bin, val)]) -- ^ Input function+ -> HBuilder a b+mkHistMonoid bin out inp = MkHBuilder $ HistBuilder bin mempty fill out+ where+ fill a h = mapM_ (fillMonoid h) $ inp a
+ Data/Histogram/Parse.hs view
@@ -0,0 +1,46 @@+module Data.Histogram.Parse ( ws+ , eol+ , value+ , maybeValue+ , keyword+ ) where++import Text.Read+import Text.ParserCombinators.ReadP (ReadP, many, satisfy, char, string)+import Text.ParserCombinators.ReadPrec++-- Whitespaces+ws :: ReadP String+ws = many $ satisfy (`elem` " \t")++-- End of line+eol :: ReadP Char+eol = char '\n'++-- Equal sign+eq :: ReadP ()+eq = ws >> char '=' >> return ()++-- Key+key :: String -> ReadP String+key s = char '#' >> ws >> string s +++getVal :: Read a => ReadPrec a+getVal = do x <- readPrec+ lift eol + return x++-- Key value pair+value :: Read a => String -> ReadPrec a+value str = do lift $ key str >> eq+ getVal++-- Return optional value+maybeValue :: Read a => String -> ReadPrec (Maybe a)+maybeValue str = do lift $ key str >> eq+ (lift $ ws >> eol >> return Nothing) <++ (Just `fmap` getVal)++-- Keyword+keyword :: String -> ReadPrec ()+keyword str = lift $ key str >> ws >> eol >> return ()
+ Data/Histogram/ST.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE Rank2Types #-}+-- |+-- Module : Data.Histogram.ST+-- Copyright : Copyright (c) 2009, Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- License : BSD3+-- Maintainer : Alexey Khudyakov <alexey.skladnoy@gmail.com>+-- Stability : experimental+-- +-- Mutable histograms.++module Data.Histogram.ST ( -- * Mutable histograms+ HistogramST(..)+ , newHistogramST+ , fillOne+ , fillOneW+ , fillMonoid+ , freezeHist++ -- * Accumulators+ , Accumulator(..)+ , Accum(Accum)++ , accumList+ , accumHist++ , fillHistograms+ ) where+++import Control.Monad.ST++import Data.Array.Vector+import Data.Monoid++import Data.Histogram+import Data.Histogram.Bin+++----------------------------------------------------------------+-- Mutable histograms+----------------------------------------------------------------++-- | Mutable histogram.+data HistogramST s bin a where+ HistogramST :: (Bin bin, UA a) => + bin+ -> MUArr a s -- Over/underflows+ -> MUArr a s -- Data+ -> HistogramST s bin a++-- | Create new mutable histogram. All bins are set to zero element as+-- passed to function.+newHistogramST :: (Bin bin, UA a) => a -> bin -> ST s (HistogramST s bin a)+newHistogramST zero bin = do+ uo <- newMU 2+ writeMU uo 0 zero >> writeMU uo 1 zero+ a <- newMU (nBins bin)+ mapM_ (\i -> writeMU a i zero) [0 .. (lengthMU a) - 1]+ return $ HistogramST bin uo a++-- | Put one value into histogram+fillOne :: Num a => HistogramST s bin a -> BinValue bin -> ST s ()+fillOne (HistogramST bin uo arr) x+ | i < 0 = writeMU uo 0 . (+1) =<< readMU uo 0+ | i >= lengthMU arr = writeMU uo 1 . (+1) =<< readMU uo 1+ | otherwise = writeMU arr i . (+1) =<< readMU arr i+ where+ i = toIndex bin x++-- | Put one value into histogram with weight+fillOneW :: Num a => HistogramST s bin a -> (BinValue bin, a) -> ST s ()+fillOneW (HistogramST bin uo arr) (x,w)+ | i < 0 = writeMU uo 0 . (+w) =<< readMU uo 0+ | i >= lengthMU arr = writeMU uo 1 . (+w) =<< readMU uo 1+ | otherwise = writeMU arr i . (+w) =<< readMU arr i+ where+ i = toIndex bin x++-- | Put one monoidal element+fillMonoid :: Monoid a => HistogramST s bin a -> (BinValue bin, a) -> ST s ()+fillMonoid (HistogramST bin uo arr) (x,m)+ | i < 0 = writeMU uo 1 . (flip mappend m) =<< readMU uo 0+ | i >= lengthMU arr = writeMU uo 1 . (flip mappend m) =<< readMU uo 1+ | otherwise = writeMU arr i . (flip mappend m) =<< readMU arr i+ where+ i = toIndex bin x++-- | Create immutable histogram from mutable one. This operation involve copying.+freezeHist :: HistogramST s bin a -> ST s (Histogram bin a)+freezeHist (HistogramST bin uo arr) = do+ [u,o] <- fromU `fmap` unsafeFreezeAllMU uo -- Is it safe???+ -- Copy array+ let len = lengthMU arr+ tmp <- newMU len+ memcpyOffMU arr tmp 0 0 len+ a <- unsafeFreezeAllMU tmp+ return $ Histogram bin (Just (u,o)) a++++----------------------------------------------------------------+-- Accumulator typeclass+----------------------------------------------------------------+-- | This is class with accumulation semantics. It's used to fill many+-- histogram at once. It accept values of type a and return data of type b.+class Accumulator h where+ -- | Put one element into accumulator+ putOne :: h s a b -> a -> ST s () + -- | Extract data from historam+ extract :: Monoid b => (h s a b) -> ST s b++-- | Put many elements in histogram(s) at once +putMany :: Accumulator h => h s a b -> [a] -> ST s () +putMany !h = mapM_ (putOne h) ++-- | Put all values into histogram and return result+fillHistograms :: Monoid b => (forall s . ST s (Accum s a b)) -> [a] -> b+fillHistograms h xs = runST $ do h' <- h+ putMany h' xs+ extract h'++----------------------------------------------------------------+-- GADT wrapper +----------------------------------------------------------------+-- | Abstract wrapper for histograms. +data Accum s a b where+ Accum :: Accumulator h => h s a b -> Accum s a b++instance Accumulator Accum where+ putOne !(Accum h) !x = putOne h x + extract !(Accum h) = extract h+++----------------------------------------------------------------+-- List of histograms+----------------------------------------------------------------+newtype AccumList s a b = AccumList [Accum s a b]+ +-- | Wrap list of histograms into one 'Accum'+accumList :: [ST s (Accum s a b)] -> ST s (Accum s a b)+accumList l = (Accum . AccumList) `fmap` sequence l++instance Accumulator AccumList where+ putOne !(AccumList l) !x = mapM_ (flip putOne $ x) l + extract !(AccumList l) = mconcat `fmap` mapM extract l +++----------------------------------------------------------------+-- Generic histogram +----------------------------------------------------------------+data AccumHist s a b where+ AccumHist :: (Bin bin) =>+ (a -> HistogramST s bin val -> ST s ())+ -> (Histogram bin val -> b)+ -> HistogramST s bin val+ -> AccumHist s a b++-- | Accumulator for arbitrary 'HistogramST' based histogram+accumHist :: (Bin bin) =>+ (a -> HistogramST s bin val -> ST s ())+ -> (Histogram bin val -> b)+ -> HistogramST s bin val+ -> ST s (Accum s a b)+accumHist inp out h = return . Accum $ AccumHist inp out h++instance Accumulator AccumHist where+ putOne !(AccumHist inp _ st) !x = inp x st+ extract !(AccumHist _ out st) = out `fmap` freezeHist st
+ LICENSE view
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ histogram-fill.cabal view
@@ -0,0 +1,26 @@+Name: histogram-fill+Version: 0.1.0+Cabal-Version: >= 1.2+License: BSD3+License-File: LICENSE+Author: Alexey Khudyakov+Maintainer: Alexey Khudyakov <alexey.skladnoy@gmail.com>+Homepage: http://bitbucket.org/Shimuuar/histogram-fill/+Category: Data+Build-Type: Simple+Synopsis: Library for histograms creation.+Description: + This is library for histograms filling. Its aim to provide+ convenient way to create and fill histograms. + .+ This is very much work in progress so expect API breakage in future relesases.+++Library+ Build-Depends: base >=3 && <5, uvector >=0.1 && <0.2+ Exposed-modules: Data.Histogram+ Data.Histogram.Fill + Data.Histogram.Bin+ Data.Histogram.ST+ Other-modules: Data.Histogram.Parse+ Ghc-options: -O2 -Wall -auto-all