HMap-1.3.0: Fast heterogeneous maps and unconstrained typeable-like functionality.

Safe HaskellNone





data HKey s a Source #

The datatype of Keys.

The scope of this key. This can either be T for top-level keys created with createKey or an existential type for keys introduced by withKey (or with the Key monad KeyM).
The type of things that can be sorted at this key.

For example, Key T Int is a top-level key that can be used to store values of type Int in a heterogenous map.

withKey :: (forall x. HKey x a -> b) -> b Source #

O(1). Scopes a key to the given function The key cannot escape the function (because of the existential type).

The implementation actually *creates* a key, but because the key cannot escape the given function f, there is no way to observe that if we run withKey f twice, that it will get a different key the second time.

data T Source #

The scope of top-level keys.

createKey :: IO (HKey T a) Source #

O(1). Create a new top-level key.

Key Monad

type KeyM s a = KeyT s Identity a Source #

A monad that can be used to create keys Keys cannot escape the monad, analogous to the ST Monad. Can be used instead of the withKey function if you need an statically unknown number of keys.

The applicative instance is more non-strict than the standard ap:

let hang = getKey >> hang in snd $ runIdentity $ runKeyT $ pure (,) * hang * (getKey >> return 2) does not hang, but with ap it does.

data KeyT s m a Source #


MonadTrans (KeyT s) Source # 


lift :: Monad m => m a -> KeyT s m a #

Monad m => Monad (KeyT s m) Source # 


(>>=) :: KeyT s m a -> (a -> KeyT s m b) -> KeyT s m b #

(>>) :: KeyT s m a -> KeyT s m b -> KeyT s m b #

return :: a -> KeyT s m a #

fail :: String -> KeyT s m a #

Monad m => Functor (KeyT s m) Source # 


fmap :: (a -> b) -> KeyT s m a -> KeyT s m b #

(<$) :: a -> KeyT s m b -> KeyT s m a #

MonadFix m => MonadFix (KeyT s m) Source # 


mfix :: (a -> KeyT s m a) -> KeyT s m a #

Monad m => Applicative (KeyT s m) Source # 


pure :: a -> KeyT s m a #

(<*>) :: KeyT s m (a -> b) -> KeyT s m a -> KeyT s m b #

liftA2 :: (a -> b -> c) -> KeyT s m a -> KeyT s m b -> KeyT s m c #

(*>) :: KeyT s m a -> KeyT s m b -> KeyT s m b #

(<*) :: KeyT s m a -> KeyT s m b -> KeyT s m a #

type Key s = KeyT s Identity Source #

runKey :: (forall s. Key s a) -> a Source #

newKey :: KeyT s m (HKey s a) Source #

Obtain a key in the key monad

getKey :: KeyT s m (HKey s a) Source #

Obtain a key in the key monad, alias for newKey

keyTSplit :: KeyT s m a -> KeyT s m (m a) Source #

Split of a keyT computation.

As an analogy, think of a random number generator some random number generator can be split, from one random number generator we obtain two distinct random number generator that are unrelated.

The KeyT monad gives us access to a name source, this operation allows us to split the name source. The generated name from both this and the split off computation have the same scope, but are otherwise underlated.

Notice that the sharing of the same scope is not a problem because the monad ensures referential transparency.

runKeyT :: forall m a. Monad m => (forall s. KeyT s m a) -> m a Source #

Run a key monad. Existential type makes sure keys cannot escape.