monadic-bang-0.2.1.0: GHC plugin to desugar ! into do-notation
Safe HaskellNone
LanguageGHC2021

MonadicBang.Internal

Synopsis

Documentation

data Loc Source #

Constructors

MkLoc 

Fields

Instances

Instances details
Show Loc Source # 
Instance details

Defined in MonadicBang.Internal

Methods

showsPrec :: Int -> Loc -> ShowS #

show :: Loc -> String #

showList :: [Loc] -> ShowS #

Eq Loc Source # 
Instance details

Defined in MonadicBang.Internal

Methods

(==) :: Loc -> Loc -> Bool #

(/=) :: Loc -> Loc -> Bool #

Ord Loc Source # 
Instance details

Defined in MonadicBang.Internal

Methods

compare :: Loc -> Loc -> Ordering #

(<) :: Loc -> Loc -> Bool #

(<=) :: Loc -> Loc -> Bool #

(>) :: Loc -> Loc -> Bool #

(>=) :: Loc -> Loc -> Bool #

max :: Loc -> Loc -> Loc #

min :: Loc -> Loc -> Loc #

data InScope Source #

To keep track of which local variables in scope may be used

If local variables are defined within the same statement as a !, but outside of that !, they must not be used within this !, since their desugaring would make them escape their scope.

Constructors

MkInScope 

Fields

Instances

Instances details
Monoid InScope Source # 
Instance details

Defined in MonadicBang.Internal

Semigroup InScope Source # 
Instance details

Defined in MonadicBang.Internal

isInvalid :: forall (sig :: (Type -> Type) -> Type -> Type) m. Has (Reader InScope) sig m => OccName -> m Bool Source #

bangLoc :: Loc -> Loc Source #

Decrement column by one to get the location of a !

bangSpan :: SrcSpan -> SrcSpan Source #

Decrement start by one column to get the location of a !

bangSrcLoc :: SrcLoc -> SrcLoc Source #

Decrement column by one to get the location of a !

pattern ExprLoc :: Loc -> Expr -> LExpr Source #

Used to extract the Loc of a located expression

type family HandleFailure (canFail :: Bool) = (t :: (Type -> Type) -> Type -> Type) | t -> canFail where ... Source #

class MonadTrans t => HandlingMonadTrans (t :: (Type -> Type) -> Type -> Type) where Source #

Methods

toMaybeT :: forall (m :: Type -> Type) a. Monad m => t m a -> MaybeT m a Source #

Instances

Instances details
HandlingMonadTrans MaybeT Source # 
Instance details

Defined in MonadicBang.Internal

Methods

toMaybeT :: forall (m :: Type -> Type) a. Monad m => MaybeT m a -> MaybeT m a Source #

HandlingMonadTrans (IdentityT :: (Type -> Type) -> Type -> Type) Source # 
Instance details

Defined in MonadicBang.Internal

Methods

toMaybeT :: forall (m :: Type -> Type) a. Monad m => IdentityT m a -> MaybeT m a Source #

class Typeable (AstType a) => Handle (a :: k) where Source #

Associated Types

type CanFail (a :: k) :: Bool Source #

type AstType (a :: k) = (r :: Type) | r -> k a Source #

type Effects (a :: k) :: (Type -> Type) -> Type -> Type Source #

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail a) m', Has (Effects a) sig m') => Handler m (AstType a) Source #

Instances

Instances details
Handle StmtLR Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail StmtLR 
Instance details

Defined in MonadicBang.Internal

type AstType StmtLR 
Instance details

Defined in MonadicBang.Internal

type Effects StmtLR 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail StmtLR) m', Has (Effects StmtLR) sig m') => Handler m (AstType StmtLR) Source #

Handle HsBindLR Source #

We keep track of any local binds, to prevent the user from using them with ! in situations where they would be evacuated to a place where they're not in scope

The plugin would still work without this, but might accept programs that shouldn't be accepted, with unexpected semantics. E.g:

do let s = pure "outer"
   let s = pure "inner" in putStrLn !s

You might expect this to print inner, but it would actually print outer, since it would be desugared to

do let s = pure "outer"
   <!s> <- s
   let s = pure "inner" in print <!s>

With this function, the plugin will instead throw an error saying that s cannot be used here.

If the first s weren't defined, the user would, without this function, get an error saying that s is not in scope, at the call site. Here, we instead throw a more informative error.

If only the first s were defined, i.e.

do let s = pure "outer"
   putStrLn !s

it would be valid code.

Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail HsBindLR 
Instance details

Defined in MonadicBang.Internal

type AstType HsBindLR 
Instance details

Defined in MonadicBang.Internal

type Effects HsBindLR 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail HsBindLR) m', Has (Effects HsBindLR) sig m') => Handler m (AstType HsBindLR) Source #

Handle GRHSs Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail GRHSs 
Instance details

Defined in MonadicBang.Internal

type AstType GRHSs 
Instance details

Defined in MonadicBang.Internal

type Effects GRHSs 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail GRHSs) m', Has (Effects GRHSs) sig m') => Handler m (AstType GRHSs) Source #

Handle Match Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail Match 
Instance details

Defined in MonadicBang.Internal

type AstType Match 
Instance details

Defined in MonadicBang.Internal

type Effects Match 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail Match) m', Has (Effects Match) sig m') => Handler m (AstType Match) Source #

Handle MatchGroup Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail MatchGroup 
Instance details

Defined in MonadicBang.Internal

type AstType MatchGroup 
Instance details

Defined in MonadicBang.Internal

type Effects MatchGroup 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail MatchGroup) m', Has (Effects MatchGroup) sig m') => Handler m (AstType MatchGroup) Source #

Handle HsExpr Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail HsExpr 
Instance details

Defined in MonadicBang.Internal

type AstType HsExpr 
Instance details

Defined in MonadicBang.Internal

type Effects HsExpr 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail HsExpr) m', Has (Effects HsExpr) sig m') => Handler m (AstType HsExpr) Source #

Handle Pat Source # 
Instance details

Defined in MonadicBang.Internal

Associated Types

type CanFail Pat 
Instance details

Defined in MonadicBang.Internal

type CanFail Pat = 'True
type AstType Pat 
Instance details

Defined in MonadicBang.Internal

type Effects Pat 
Instance details

Defined in MonadicBang.Internal

Methods

handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail Pat) m', Has (Effects Pat) sig m') => Handler m (AstType Pat) Source #

handle :: forall {k} (a :: k) (sig :: (Type -> Type) -> Type -> Type) m. (Handle a, CanFail a ~ 'False, Has (Effects a) sig m) => Handler m (AstType a) Source #

try :: forall {k} (e :: k) (sig :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a. (HandlingMonadTrans (HandleFailure (CanFail e)), Typeable a, Handle e, Monad m, Has (Effects e) sig m) => Try m a Source #

fillHoles :: forall a (sig :: (Type -> Type) -> Type -> Type) m. (Data a, Has (PsErrors :+: (Reader Options :+: ((Uniques :: (Type -> Type) -> Type -> Type) :+: (LocalVars :+: Reader DynFlags)))) sig m) => Map Loc LExpr -> Handler m a Source #

Replace holes in an AST whenever an expression with the corresponding source span can be found in the given list.

evac :: forall a (sig :: (Type -> Type) -> Type -> Type) m. (Has Fill sig m, Data a) => Handler m a Source #

tryEvac :: forall (m :: Type -> Type) a. Monad m => [Try m a] -> Try m a Source #

usualTries :: forall (sig :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a. (Has Fill sig m, Data a) => [Try m a] Source #

ignore :: forall e (m :: Type -> Type) a. (Monad m, Typeable a, Typeable e) => Try m a Source #

evacPats :: forall a m (sig :: (Type -> Type) -> Type -> Type). (Has (Fill :+: State InScope) sig m, Data a) => Handler m a Source #

evacuate !s in pattern and collect all the names it binds

addStmts :: forall (sig :: (Type -> Type) -> Type -> Type) m. Has (PsErrors :+: ((HoleFills :: (Type -> Type) -> Type -> Type) :+: ((Uniques :: (Type -> Type) -> Type -> Type) :+: (LocalVars :+: Reader DynFlags)))) sig m => Handler m [ExprLStmt GhcPs] Source #

Find all !s in the given statements and combine the resulting bind statements into lists, with the original statements being the last one in each list - then concatenate these lists

type HoleFills = Offer Loc LExpr :: k -> Type -> Type Source #

type LocalVars = Reader InScope :+: Writer OccSet Source #

We keep track of variables that are bound in lambdas, cases, etc., since these are variables that will not be accessible in the surrounding 'do'-block, and must therefore not be used. The Reader is used to find out what local variables are in scope, the Writer is used to inform callers which local variables have been bound.

data BindStmt Source #

Constructors

RdrName :<- LExpr 

bangVar :: forall (sig :: (Type -> Type) -> Type -> Type) m. Has ((Uniques :: (Type -> Type) -> Type -> Type) :+: Reader DynFlags) sig m => LExpr -> Loc -> m RdrName Source #

Use the !'d expression if it's short enough, or else abbreviate with ... We don't need to worry about shadowing other !'d expressions: - For the user, we add line and column numbers to the name - For the compiler, we use a unique instead of the name

locVar :: forall (sig :: (Type -> Type) -> Type -> Type) m. Has (Uniques :: (Type -> Type) -> Type -> Type) sig m => String -> SrcSpan -> Loc -> m RdrName Source #

tellOne :: forall w (sig :: (Type -> Type) -> Type -> Type) m. Has (Writer (DList w)) sig m => w -> m () Source #

tellLocalVar :: forall (sig :: (Type -> Type) -> Type -> Type) m. Has (Writer OccSet) sig m => OccName -> m () Source #