polysemy-zoo-0.8.1.0: Experimental, user-contributed effects and interpreters for polysemy
Safe HaskellTrustworthy
LanguageHaskell2010

Polysemy.Fresh

Synopsis

Effect

data Fresh uniq m a where Source #

An effect for creating unique objects which may be used as references, a la Unique. Polymorphic code making use of Fresh is expected to place constraints upon uniq as necessary.

Any interpreter for Fresh has the responsibilty of ensuring that any call to fresh produces an object that never compares equal to an object produced by a previous call to fresh.

Constructors

Fresh :: Fresh uniq m uniq 

Actions

fresh :: forall uniq r. Member (Fresh uniq) r => Sem r uniq Source #

Interpretations

freshToIO :: Member (Embed IO) r => Sem (Fresh Unique ': r) a -> Sem r a Source #

Runs a Fresh effect through generating Uniques using IO.

Unsafe Interpretations

runFreshEnumUnsafe :: forall n a r. Enum n => Sem (Fresh n ': r) a -> Sem r a Source #

Run a Fresh effect purely by specifying an Enum to be used as the type of unique objects.

Beware: This is safe only if:

  1. This is run after all interpreters which may revert local state or produce multiple, inconsistent instances of local state. This includes interpreters that may backtrack or produce multiple results (such as runError or runNonDet).
  2. You don't use any interpreter which may cause the final monad to revert local state or produce multiple, inconsistent instances of local state. This includes certain Final/lower- interpeters such as lowerError or errorToFinal, as well as interpreters for Async.

Prefer freshToIO whenever possible. If you can't use runFreshEnumUnsafe safely, nor use freshToIO, consider runFreshUnsafePerformIO.

runFreshUnsafePerformIO :: Sem (Fresh Unique ': r) a -> Sem r a Source #

Runs a Fresh effect through generating Uniques using unsafePerformIO.

Ironically, despite the fact that this uses unsafePerformIO, and runFreshUnsafe uses no unsafe operations whatsoever, this is still typically safer to use than runFreshUnsafe, although runFreshUnsafe is perhaps more efficient.

The worst thing that this particular use of unsafePerformIO could result in is the loss of referential transparency, as rerunning an interpreter stack using runFreshUnsafePerformIO will create different Uniques. This should never matter.

This could be potentially be less efficient than runFreshUnsafe.

If you ever observe that multiple invocations of fresh produce the same Unique under runFreshUnsafePerformIO, then open an issue over at the GitHub repository.