{-# OPTIONS_HADDOCK not-home #-} module Data.Urn.Common ( -- * Types Urn(), Weight, MonadSample(), -- * 'Urn' properties size, totalWeight, -- * Constructing 'Urn's singleton, fromList, fromNonEmpty, -- * Inserting into 'Urn's insert, addToUrn ) where import Data.List.NonEmpty (NonEmpty(..), nonEmpty) import Data.Foldable import Data.Coerce import Data.Urn.MonadSample import Data.Urn.Internal hiding (size) import qualified Data.Urn.Internal as Internal size :: Urn a -> Word size = (coerce :: (Urn a -> Size) -> (Urn a -> Word)) Internal.size {-# INLINABLE size #-} totalWeight :: Urn a -> Weight totalWeight = weight . wtree {-# INLINABLE totalWeight #-} singleton :: Weight -> a -> Urn a singleton w a = Urn { Internal.size = 1, wtree = WLeaf w a } {-# INLINABLE singleton #-} addToUrn :: Foldable t => Urn a -> t (Weight, a) -> Urn a addToUrn = foldl' (flip $ uncurry insert) {-# INLINABLE addToUrn #-} fromList :: [(Weight,a)] -> Maybe (Urn a) fromList = fmap fromNonEmpty . nonEmpty {-# INLINABLE fromList #-} fromNonEmpty :: NonEmpty (Weight,a) -> Urn a -- fromNonEmpty ((w,t):|wts) = addToUrn (singleton w t) wts fromNonEmpty = Internal.construct -- this is O(n) now {-# INLINABLE fromNonEmpty #-}