-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix scoped within scoped incoherency. Add
runScopedNew
(#466)
- Loading branch information
1 parent
2d88b93
commit 1ff567c
Showing
7 changed files
with
258 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
module Polysemy.Opaque ( | ||
-- * Effect | ||
Opaque(..), | ||
|
||
-- * Interpreters | ||
toOpaque, | ||
fromOpaque, | ||
) where | ||
|
||
import Polysemy | ||
|
||
-- | An effect newtype meant to be used to wrap polymorphic effect variables to | ||
-- prevent them from jamming up resolution of 'Polysemy.Member'. | ||
-- For example, consider: | ||
-- | ||
-- @ | ||
-- badPut :: 'Sem' (e ': 'Polysemy.State.State' () ': r) () | ||
-- badPut = 'Polysemy.State.put' () -- error | ||
-- @ | ||
-- | ||
-- This fails to compile. This is because @e@ /could/ be | ||
-- @'Polysemy.State.State' ()@' -- in which case the 'Polysemy.State.put' | ||
-- should target it instead of the concretely provided | ||
-- @'Polysemy.State.State' ()@; as the compiler can't know for sure which effect | ||
-- should be targeted, the program is rejected. | ||
-- There are various ways to resolve this, including using 'raise' or | ||
-- 'Polysemy.Membership.subsumeUsing'. 'Opaque' provides another way: | ||
-- | ||
-- @ | ||
-- okPut :: 'Sem' (e ': 'Polysemy.State.State' () ': r) () | ||
-- okPut = 'fromOpaque' ('Polysemy.State.put' ()) -- OK | ||
-- @ | ||
-- | ||
-- 'Opaque' is most useful as a tool for library writers, in the case where some | ||
-- function of the library requires the user to work with an effect stack | ||
-- containing some polymorphic effect variables. By wrapping the polymorphic | ||
-- effect variables using 'Opaque', users of the function can use effects as | ||
-- normal, without having to use 'raise' or 'Polysemy.Membership.subsumeUsing' | ||
-- in order to have 'Polysemy.Member' resolve. The various interpreters of | ||
-- 'Polysemy.Scoped.Scoped' are examples of such usage of 'Opaque'. | ||
-- | ||
-- @since 1.9.0.0 | ||
newtype Opaque (e :: Effect) m a = Opaque (e m a) | ||
|
||
-- | Wrap 'Opaque' around the top effect of the effect stack | ||
toOpaque :: Sem (e ': r) a -> Sem (Opaque e ': r) a | ||
toOpaque = rewrite Opaque | ||
{-# INLINE toOpaque #-} | ||
|
||
-- | Unwrap 'Opaque' around the top effect of the effect stack | ||
fromOpaque :: Sem (Opaque e ': r) a -> Sem (e ': r) a | ||
fromOpaque = rewrite (\(Opaque e) -> e) | ||
{-# INLINE fromOpaque #-} |
Oops, something went wrong.