HFrequencyQueue-0.2.0.0: src/FrequencyQueue.hs
{-|
Module : FrequencyQueue
Description : Main module for FrequencyQueue
Copyright : (c) Andrea Bellandi 2014
License : GPL-3
Maintainer : bellaz89@gmai.com
Stability : experimental
Portability : POSIX
This module export the interface of FrequencyQueue.
-}
module FrequencyQueue(
-- *Types
FrequencyQueue(),
-- *Functions
-- **Creation functions
newFrequencyQueue,
-- **Basic properties
length, probabilityUnit,
-- **Pop-push functions
pushBack, popBack, popBackMax, popBackMin, getRandom, getRandomPop,
-- **Iterative functions
mapWprobability, foldWprobability,
-- **Unsafe interface
popBackUnsafe, popBackMaxUnsafe, popBackMinUnsafe, getRandomUnsafe, getRandomPopUnsafe) where
import Prelude hiding (length)
import System.IO.Unsafe(unsafePerformIO)
import FrequencyQueue.IO(FrequencyQueue)
import qualified FrequencyQueue.IO as FQIO
import Control.Monad(Functor(..))
import Data.Foldable(Foldable(..))
instance Functor FrequencyQueue where
fmap fun queue_ = mapWprobability (\(el,prob) -> (fun(el),prob)) queue_
instance Foldable FrequencyQueue where
foldr fun b0 queue_ = foldWprobability (\b (el,_) -> fun el b ) b0 queue_
-- |Create a new FrequencyQueue with a seed
newFrequencyQueue :: Int -> FrequencyQueue a
newFrequencyQueue seed = (unsafePerformIO . FQIO.newFrequencyQueue) seed
-- |Return the number of elements in the queue
length :: FrequencyQueue a -> Int
length queue_ = (unsafePerformIO . FQIO.length) queue_
-- |Return the sum of all elements' probabilities passed to the queue
probabilityUnit :: FrequencyQueue a -> Int
probabilityUnit queue_ = (unsafePerformIO . FQIO.probabilityUnit) queue_
-- |Push an element a in the queue with a corresponding relative probability
pushBack :: FrequencyQueue a -> a -> Int -> FrequencyQueue a
pushBack queue_ element_ probability_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
FQIO.pushBack newqueue_ element_ probability_
return newqueue_
-- |Pop an element of the queue. Return Nothing if the queue is empty
popBack :: FrequencyQueue a -> Maybe ((a, Int), FrequencyQueue a)
popBack queue_ = if (length queue_) == 0
then Nothing
else Just (popBackUnsafe queue_)
-- |Pop the element of the queue that have the biggest relative probability.
-- Return Nothing if the queue is empty
popBackMax :: FrequencyQueue a -> Maybe ((a, Int), FrequencyQueue a)
popBackMax queue_ = if (length queue_) == 0
then Nothing
else Just (popBackMaxUnsafe queue_)
-- |Pop the element of the queue that have the smallest relative probability.
-- Return Nothing if the queue is empty
popBackMin :: FrequencyQueue a -> Maybe ((a, Int), FrequencyQueue a)
popBackMin queue_ = if (length queue_) == 0
then Nothing
else Just (popBackMinUnsafe queue_)
-- |Return a random element from the queue using its relative probability.
-- Return Nothing if the queue is empty
getRandom :: FrequencyQueue a -> Maybe ((a, Int), FrequencyQueue a)
getRandom queue_ = if (length queue_) == 0
then Nothing
else Just (getRandomUnsafe queue_)
-- |Pop a random element from the queue using its relative probability.
-- Return Nothing if the queue is empty
getRandomPop :: FrequencyQueue a -> Maybe ((a, Int), FrequencyQueue a)
getRandomPop queue_ = if (length queue_) == 0
then Nothing
else Just (getRandomPopUnsafe queue_)
-- |Return a new queue with the elements and relative probability mapped
-- by the function provided
mapWprobability :: ((a, Int) -> (b, Int)) -> FrequencyQueue a -> FrequencyQueue b
mapWprobability fun queue_ = unsafePerformIO $ FQIO.mapWprobability fun queue_
-- |Return a folded value made by an initial value b and a folding function
-- evaluated on the entire queue.
foldWprobability :: (b -> (a, Int) -> b) -> b -> FrequencyQueue a -> b
foldWprobability fold_fun b0 queue_ = unsafePerformIO $ FQIO.foldWprobability fold_fun b0 queue_
-- |Pop an element of the queue. Fail if empty
popBackUnsafe :: FrequencyQueue a -> ((a, Int), FrequencyQueue a)
popBackUnsafe queue_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
result <- FQIO.popBackUnsafe newqueue_
return (result, newqueue_)
-- |Pop the element of the queue that have the biggest relative probability.
-- Fail if empty
popBackMaxUnsafe :: FrequencyQueue a -> ((a, Int), FrequencyQueue a)
popBackMaxUnsafe queue_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
result <- FQIO.popBackMaxUnsafe newqueue_
return (result, newqueue_)
-- |Pop the element of the queue that have the smallest relative probability.
-- Fail if empty
popBackMinUnsafe :: FrequencyQueue a -> ((a, Int), FrequencyQueue a)
popBackMinUnsafe queue_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
result <- FQIO.popBackMinUnsafe newqueue_
return (result, newqueue_)
-- |Pop the element of the queue that have the smallest relative probability.
-- Fail if empty
getRandomUnsafe :: FrequencyQueue a -> ((a, Int), FrequencyQueue a)
getRandomUnsafe queue_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
result <- FQIO.getRandomUnsafe newqueue_
return (result, newqueue_)
-- |Pop a random element from the queue using its relative probability.
-- Fail if empty
getRandomPopUnsafe :: FrequencyQueue a -> ((a, Int), FrequencyQueue a)
getRandomPopUnsafe queue_ = unsafePerformIO $ do newqueue_ <- FQIO.cloneFrequencyQueue queue_
result <- FQIO.getRandomPopUnsafe newqueue_
return (result, newqueue_)