Copyright | (c) Donnacha Oisín Kidney 2021 |
---|---|
Maintainer | mail@doisinkidney.com |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
The Heap monad: a monad for efficient weighted search.
This module provides an implementation of the Heap monad transformer as described in:
- Donnacha Oisín Kidney and Nicolas Wu. 2021. Algebras for weighted search. Proc. ACM Program. Lang. 5, ICFP, Article 72 (August 2021), 30 pages. DOI:https://doi.org/10.1145/3473577
This monad transformer can be used to implement search algorithms like Dijkstra's algorithm (see MonusWeightedSearch.Examples.Dijkstra), or the Viterbi algorithm (MonusWeightedSearch.Examples.Viterbi), or probabilistic parsing (MonusWeightedSearch.Examples.Parsing).
The type supports nondeterminism (using the Alternative
and MonadPlus
interfaces), where each branch in a computation can be weighted by some
Monus
. A Monus
is an ordered Monoid
with some pseudo-subtraction
operator, see the Data.Monus module for more details.
Synopsis
- newtype HeapT w m a = HeapT {}
- data Node w a b
- type Heap w = HeapT w Identity
- pattern Heap :: [Node w a (Heap w a)] -> Heap w a
- runHeap :: Heap w a -> [Node w a (Heap w a)]
- fromList :: Applicative m => [(a, w)] -> HeapT w m a
- popMin :: Monus w => Heap w a -> ([a], Maybe (w, Heap w a))
- popMinT :: (Monus w, Monad m) => HeapT w m a -> m ([a], Maybe (w, HeapT w m a))
- popMinOne :: Monus w => Heap w a -> Maybe ((a, w), Heap w a)
- popMinOneT :: forall w m a. (Monus w, Monad m) => HeapT w m a -> m (Maybe ((a, w), HeapT w m a))
- flatten :: Monoid w => Heap w a -> [(a, w)]
- flattenT :: (Monad m, Monoid w) => HeapT w m a -> ListT m (a, w)
- search :: Monus w => Heap w a -> [(a, w)]
- searchT :: (Monad m, Monus w) => HeapT w m a -> m [(a, w)]
- best :: Monus w => Heap w a -> Maybe (w, a)
- bestT :: (Monad m, Monus w) => HeapT w m a -> m (Maybe (w, a))
Heap Type
The HeapT
monad transformer: a monad for weighted search.
This monad supports nondeterminism through the Alternative
and
MonadPlus
classes, but different branches in the computation may be
weighted by the w
parameter. A computation can be given a specific weight
using the MonadWriter
interface:
tell
4>>
xs
This weights the computation xs
with 4
.
Depending on the Monus
used, the order of the search can be specified.
For instance, using the Monus
in Data.Monus.Dist, we have the following:
>>>
search (fromList [('a',5), ('b', 3), ('c',6)])
[('b',3),('a',5),('c',6)]
>>>
search (fromList [('b',3), ('a',5), ('c',6)])
[('b',3),('a',5),('c',6)]
Instances
(Monad m, Monoid w) => MonadWriter w (HeapT w m) Source # | |
MonadState s m => MonadState s (HeapT w m) Source # | |
MonadReader r m => MonadReader r (HeapT w m) Source # | |
MonadError e m => MonadError e (HeapT w m) Source # | |
Defined in Control.Monad.Heap throwError :: e -> HeapT w m a # catchError :: HeapT w m a -> (e -> HeapT w m a) -> HeapT w m a # | |
MonadTrans (HeapT w) Source # | |
Defined in Control.Monad.Heap | |
Monad m => MonadFree ((,) w) (HeapT w m) Source # | |
Defined in Control.Monad.Heap | |
Monad m => Monad (HeapT w m) Source # | |
Functor m => Functor (HeapT w m) Source # | |
Monad m => Applicative (HeapT w m) Source # | |
Foldable m => Foldable (HeapT w m) Source # | |
Defined in Control.Monad.Heap fold :: Monoid m0 => HeapT w m m0 -> m0 # foldMap :: Monoid m0 => (a -> m0) -> HeapT w m a -> m0 # foldMap' :: Monoid m0 => (a -> m0) -> HeapT w m a -> m0 # foldr :: (a -> b -> b) -> b -> HeapT w m a -> b # foldr' :: (a -> b -> b) -> b -> HeapT w m a -> b # foldl :: (b -> a -> b) -> b -> HeapT w m a -> b # foldl' :: (b -> a -> b) -> b -> HeapT w m a -> b # foldr1 :: (a -> a -> a) -> HeapT w m a -> a # foldl1 :: (a -> a -> a) -> HeapT w m a -> a # toList :: HeapT w m a -> [a] # length :: HeapT w m a -> Int # elem :: Eq a => a -> HeapT w m a -> Bool # maximum :: Ord a => HeapT w m a -> a # minimum :: Ord a => HeapT w m a -> a # | |
Traversable m => Traversable (HeapT w m) Source # | |
Defined in Control.Monad.Heap | |
(Arbitrary1 m, Arbitrary w) => Arbitrary1 (HeapT w m) Source # | |
Defined in Control.Monad.Heap liftArbitrary :: Gen a -> Gen (HeapT w m a) # liftShrink :: (a -> [a]) -> HeapT w m a -> [HeapT w m a] # | |
Monad m => Alternative (HeapT w m) Source # | |
Monad m => MonadPlus (HeapT w m) Source # | |
MonadCont m => MonadCont (HeapT w m) Source # | |
(Monoid w, m ~ Identity) => IsList (HeapT w m a) Source # | |
(forall x. Eq x => Eq (m x), Eq a, Eq w) => Eq (HeapT w m a) Source # | |
(forall x. Data x => Data (m x), Typeable m, Data a, Data w) => Data (HeapT w m a) Source # | |
Defined in Control.Monad.Heap gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HeapT w m a -> c (HeapT w m a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HeapT w m a) # toConstr :: HeapT w m a -> Constr # dataTypeOf :: HeapT w m a -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HeapT w m a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HeapT w m a)) # gmapT :: (forall b. Data b => b -> b) -> HeapT w m a -> HeapT w m a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HeapT w m a -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HeapT w m a -> r # gmapQ :: (forall d. Data d => d -> u) -> HeapT w m a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> HeapT w m a -> u # gmapM :: Monad m0 => (forall d. Data d => d -> m0 d) -> HeapT w m a -> m0 (HeapT w m a) # gmapMp :: MonadPlus m0 => (forall d. Data d => d -> m0 d) -> HeapT w m a -> m0 (HeapT w m a) # gmapMo :: MonadPlus m0 => (forall d. Data d => d -> m0 d) -> HeapT w m a -> m0 (HeapT w m a) # | |
(Ord w, Ord a, forall x. Ord x => Ord (m x), Eq (HeapT w m a), Eq (ListT m (Node w a (HeapT w m a)))) => Ord (HeapT w m a) Source # | |
Defined in Control.Monad.Heap | |
(forall x. Read x => Read (m x), Read w, Read a) => Read (HeapT w m a) Source # | |
(forall x. Show x => Show (m x), Show a, Show w) => Show (HeapT w m a) Source # | |
Generic (HeapT w m a) Source # | |
Monad m => Semigroup (HeapT w m a) Source # | |
Monad m => Monoid (HeapT w m a) Source # | |
(Arbitrary1 m, Arbitrary w, Arbitrary a) => Arbitrary (HeapT w m a) Source # | |
(forall x. NFData x => NFData (m x), NFData w, NFData a) => NFData (HeapT w m a) Source # | |
Defined in Control.Monad.Heap | |
type Rep (HeapT w m a) Source # | |
Defined in Control.Monad.Heap | |
type Item (HeapT w m a) Source # | |
Defined in Control.Monad.Heap |
Instances
Bitraversable (Node w) Source # | |
Defined in Control.Monad.Heap bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Node w a b -> f (Node w c d) # | |
Bifoldable (Node w) Source # | |
Bifunctor (Node w) Source # | |
Generic1 (Node w a :: Type -> Type) Source # | |
Functor (Node w a) Source # | |
Foldable (Node w a) Source # | |
Defined in Control.Monad.Heap fold :: Monoid m => Node w a m -> m # foldMap :: Monoid m => (a0 -> m) -> Node w a a0 -> m # foldMap' :: Monoid m => (a0 -> m) -> Node w a a0 -> m # foldr :: (a0 -> b -> b) -> b -> Node w a a0 -> b # foldr' :: (a0 -> b -> b) -> b -> Node w a a0 -> b # foldl :: (b -> a0 -> b) -> b -> Node w a a0 -> b # foldl' :: (b -> a0 -> b) -> b -> Node w a a0 -> b # foldr1 :: (a0 -> a0 -> a0) -> Node w a a0 -> a0 # foldl1 :: (a0 -> a0 -> a0) -> Node w a a0 -> a0 # toList :: Node w a a0 -> [a0] # length :: Node w a a0 -> Int # elem :: Eq a0 => a0 -> Node w a a0 -> Bool # maximum :: Ord a0 => Node w a a0 -> a0 # minimum :: Ord a0 => Node w a a0 -> a0 # | |
Traversable (Node w a) Source # | |
(Eq a, Eq w, Eq b) => Eq (Node w a b) Source # | |
(Data w, Data a, Data b) => Data (Node w a b) Source # | |
Defined in Control.Monad.Heap gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Node w a b -> c (Node w a b) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Node w a b) # toConstr :: Node w a b -> Constr # dataTypeOf :: Node w a b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Node w a b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Node w a b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Node w a b -> Node w a b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Node w a b -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Node w a b -> r # gmapQ :: (forall d. Data d => d -> u) -> Node w a b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Node w a b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Node w a b -> m (Node w a b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Node w a b -> m (Node w a b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Node w a b -> m (Node w a b) # | |
(Ord a, Ord w, Ord b) => Ord (Node w a b) Source # | |
(Read a, Read w, Read b) => Read (Node w a b) Source # | |
(Show a, Show w, Show b) => Show (Node w a b) Source # | |
Generic (Node w a b) Source # | |
(NFData w, NFData a, NFData b) => NFData (Node w a b) Source # | |
Defined in Control.Monad.Heap | |
type Rep1 (Node w a :: Type -> Type) Source # | |
Defined in Control.Monad.Heap type Rep1 (Node w a :: Type -> Type) = D1 ('MetaData "Node" "Control.Monad.Heap" "monus-weighted-search-0.2.0.0-inplace" 'False) (C1 ('MetaCons "Leaf" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons ":<" ('InfixI 'RightAssociative 5) 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 w) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1)) | |
type Rep (Node w a b) Source # | |
Defined in Control.Monad.Heap type Rep (Node w a b) = D1 ('MetaData "Node" "Control.Monad.Heap" "monus-weighted-search-0.2.0.0-inplace" 'False) (C1 ('MetaCons "Leaf" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons ":<" ('InfixI 'RightAssociative 5) 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 w) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 b))) |
Non-transformer form
pattern Heap :: [Node w a (Heap w a)] -> Heap w a Source #
The constructor for the non-transformer Heap
type.
Constructing Heaps
fromList :: Applicative m => [(a, w)] -> HeapT w m a Source #
Build a heap from a list of values paired with their weights.
Popping the smallest elements
popMinT :: (Monus w, Monad m) => HeapT w m a -> m ([a], Maybe (w, HeapT w m a)) Source #
The monadic variant of popMin
.
Popping the smallest element
popMinOneT :: forall w m a. (Monus w, Monad m) => HeapT w m a -> m (Maybe ((a, w), HeapT w m a)) Source #
The monadic variant of popMinOne
.
Turning into a cons-list
flatten :: Monoid w => Heap w a -> [(a, w)] Source #
O(n). Return all the elements of the heap, not in order of their weights, paired with their weights.
>>>
flatten (fromList [('a',5), ('b', 3), ('c',6)])
[('a',5),('b',3),('c',6)]
flattenT :: (Monad m, Monoid w) => HeapT w m a -> ListT m (a, w) Source #
The monadic version of flatten
.
Searching the whole heap
search :: Monus w => Heap w a -> [(a, w)] Source #
O(n log n). Return all of the elements in the heap, in order, paired with their weights.