-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Disambiguate obvious uses of effects. -- -- Please see the README on GitHub at -- https://github.com/polysemy-research/polysemy/tree/master/polysemy-plugin#readme @package polysemy-plugin @version 0.4.2.0 module Polysemy.Plugin.Fundep.Stuff -- | All of the things from "polysemy" that we need access to in the -- plugin. When l ~ 'Locations, each of these is just a pair of -- strings. When l ~ 'Things, it's actually references to the -- stuff. data PolysemyStuff (l :: LookupState) PolysemyStuff :: ThingOf l Class -> ThingOf l TyCon -> PolysemyStuff (l :: LookupState) [findClass] :: PolysemyStuff (l :: LookupState) -> ThingOf l Class [semTyCon] :: PolysemyStuff (l :: LookupState) -> ThingOf l TyCon -- | Data kind for ThingOf. data LookupState Locations :: LookupState Things :: LookupState -- | Lookup all of the PolysemyStuff. polysemyStuff :: TcPluginM (PolysemyStuff 'Things) instance Polysemy.Plugin.Fundep.Stuff.CanLookup Class.Class instance Polysemy.Plugin.Fundep.Stuff.CanLookup TyCon.TyCon module Polysemy.Plugin.Fundep.Unification -- | The context in which we're attempting to solve a constraint. data SolveContext -- | In the context of a function definition. The Set TyVar is all -- of the skolems that exist in the [G] constraints for this function. FunctionDef :: Set TyVar -> SolveContext -- | In the context of running an interpreter. The Bool corresponds -- to whether we are only trying to solve a single Member -- constraint right now. If so, we *must* produce a unification wanted. InterpreterUse :: Bool -> SolveContext -- | Depending on the context in which we're solving a constraint, we may -- or may not want to force a unification of effects. For example, when -- defining user code whose type is Member (State Int) r => -- ..., if we see get :: Sem r s, we should unify s ~ -- Int. mustUnify :: SolveContext -> Bool -- | Determine whether or not two effects are unifiable. -- -- All free variables in [W] constraints are considered skolems, and thus -- are not allowed to unify with anything but themselves. This properly -- handles all cases in which we are unifying ambiguous [W] constraints -- (which are true type variables) against [G] constraints. unify :: SolveContext -> Type -> Type -> Maybe TCvSubst tryUnifyUnivarsButNotSkolems :: Set TyVar -> Type -> Type -> Maybe TCvSubst -- | A wrapper for two types that we want to say have been unified. data Unification Unification :: OrdType -> OrdType -> Unification [_unifyLHS] :: Unification -> OrdType [_unifyRHS] :: Unification -> OrdType -- | Types don't have Eq or Ord instances by default, -- even though there are functions in GHC that implement these -- operations. This newtype gives us those instances. newtype OrdType OrdType :: Type -> OrdType [getOrdType] :: OrdType -> Type -- | Filter out the unifications we've already emitted, and then give back -- the things we should put into the S.Set Unification, and the -- new constraints we should emit. unzipNewWanteds :: Set Unification -> [(Unification, Ct)] -> ([Unification], [Ct]) instance GHC.Classes.Ord Polysemy.Plugin.Fundep.Unification.SolveContext instance GHC.Classes.Eq Polysemy.Plugin.Fundep.Unification.SolveContext instance GHC.Classes.Ord Polysemy.Plugin.Fundep.Unification.Unification instance GHC.Classes.Eq Polysemy.Plugin.Fundep.Unification.Unification instance GHC.Classes.Eq Polysemy.Plugin.Fundep.Unification.OrdType instance GHC.Classes.Ord Polysemy.Plugin.Fundep.Unification.OrdType module Polysemy.Plugin.Fundep.Utils -- | Returns the head of the list iff there is exactly one element. singleListToJust :: [a] -> Maybe a -- | Like when, but in the context of an Alternative. whenA :: (Monad m, Alternative z) => Bool -> m a -> m (z a) -- | Count the number of times a is present in the list. countLength :: Eq a => [a] -> [(a, Int)] module Polysemy.Plugin.Fundep fundepPlugin :: TcPlugin instance GHC.Classes.Eq Polysemy.Plugin.Fundep.PredType' instance GHC.Classes.Ord Polysemy.Plugin.Fundep.PredType' -- | A typechecker plugin that can disambiguate "obvious" uses of effects -- in Polysemy. -- -- Example: -- -- Consider the following program: -- --
--   foo :: Member (State Int) r => Sem r ()
--   foo = put 10
--   
-- -- What does this program do? Any human will tell you that it changes the -- state of the Int to 10, which is clearly what's meant. -- -- Unfortunately, Polysemy can't work this out on its own. Its reasoning -- is "maybe you wanted to change some other State effect which is -- also a Num, but you just forgot to add a Member -- constraint for it." -- -- This is obviously insane, but it's the way the cookie crumbles. -- Plugin is a typechecker plugin which will disambiguate the -- above program (and others) so the compiler will do what you want. -- -- Usage: -- -- Add the following line to your package configuration: -- --
--   ghc-options: -fplugin=Polysemy.Plugin
--   
-- -- Limitations: -- -- The Plugin will only disambiguate effects if there is exactly -- one relevant constraint in scope. For example, it will not -- disambiguate the following program: -- --
--   bar :: Members '[ State Int
--                   , State Double
--                   ] r => Sem r ()
--   bar = put 10
--   
-- -- because it is now unclear whether you're attempting to set the -- Int or the Double. Instead, you can manually write a -- type application in this case. -- --
--   bar :: Members '[ State Int
--                   , State Double
--                   ] r => Sem r ()
--   bar = put @Int 10
--   
module Polysemy.Plugin plugin :: Plugin