module Data.Urn.Common (
Urn(), Weight, MonadSample(),
size, totalWeight,
singleton,
fromList, fromNonEmpty,
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
totalWeight :: Urn a -> Weight
totalWeight = weight . wtree
singleton :: Weight -> a -> Urn a
singleton w a = Urn { Internal.size = 1, wtree = WLeaf w a }
addToUrn :: Foldable t => Urn a -> t (Weight, a) -> Urn a
addToUrn = foldl' (flip $ uncurry insert)
fromList :: [(Weight,a)] -> Maybe (Urn a)
fromList = fmap fromNonEmpty . nonEmpty
fromNonEmpty :: NonEmpty (Weight,a) -> Urn a
fromNonEmpty = Internal.construct