packages feed

effectful-th (empty) → 1.0.0.0

raw patch · 6 files changed

+729/−0 lines, 6 filesdep +basedep +containersdep +effectful

Dependencies added: base, containers, effectful, effectful-th, exceptions, template-haskell, th-abstraction

Files

+ CHANGELOG.md view
@@ -0,0 +1,2 @@+# effectful-th-1.0.0.0 (2022-07-13)+* Initial release.
+ LICENSE view
@@ -0,0 +1,64 @@+Copyright (c) 2021-2022, Andrzej Rybczak++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Andrzej Rybczak nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++This software incorporates code from the cleff package (available from+https://hackage.haskell.org/package/cleff) under the following license:++Copyright Xy Ren (c) 2021++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Xy Ren nor the names of other contributors+      may be used to endorse or promote products derived from this+      software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,173 @@+# effectful++[![Build Status](https://github.com/haskell-effectful/effectful/workflows/Haskell-CI/badge.svg?branch=master)](https://github.com/haskell-effectful/effectful/actions?query=branch%3Amaster)+[![Hackage](https://img.shields.io/hackage/v/effectful.svg)](https://hackage.haskell.org/package/effectful)+[![Dependencies](https://img.shields.io/hackage-deps/v/effectful.svg)](https://packdeps.haskellers.com/feed?needle=andrzej@rybczak.net)+[![Stackage LTS](https://www.stackage.org/package/effectful/badge/lts)](https://www.stackage.org/lts/package/effectful)+[![Stackage Nightly](https://www.stackage.org/package/effectful/badge/nightly)](https://www.stackage.org/nightly/package/effectful)+++<img src="https://user-images.githubusercontent.com/387658/127747903-f728437f-2ee4-47b8-9f0c-5102fd44c8e4.png" width="128">++An easy to use, fast extensible effects library with seamless integration with+the existing Haskell ecosystem.++Main features:++1. Very fast+   ([benchmarks](https://github.com/haskell-effectful/effectful/tree/master/benchmarks/README.md)).++2. Easy to use API (comparable with usage of the [MonadUnliftIO](https://hackage.haskell.org/package/unliftio-core/docs/Control-Monad-IO-Unlift.html#t:MonadUnliftIO) class).++3. Correct semantics in presence of runtime exceptions (no more discarded state+   updates).++4. Seamless integration with the existing ecosystem (`exceptions`,+   `monad-control`, `unliftio-core`, `resourcet` etc.).++5. Support for thread local and shared state (e.g. `StateT` provides a thread+   local state, while `MVar` holds a shared state, both approaches have their+   merits).++6. Support for statically (implementation determined at compile time) and+   dynamically (implementation determined at run time) dispatched effects.++## Motivation++Do we really need yet another library for handling effects? There's+[freer-simple](https://hackage.haskell.org/package/freer-simple),+[fused-effects](https://hackage.haskell.org/package/fused-effects),+[polysemy](https://hackage.haskell.org/package/polysemy),+[eff](https://github.com/hasura/eff) and probably a few more.++Unfortunately, of all of them only `eff` is a promising proposition because of+reasonable performance characteristics (see the talk [Effects for+Less](https://www.youtube.com/watch?v=0jI-AlWEwYI) for more information) and+potential for good interoperability with the existing ecosystem.++The second point is arguably the most important, because it allows focusing on+things that matter instead of reinventing all kinds of wheels, hence being a+necessary condition for broader adoption of the library.++However, `eff` uses delimited continuations underneath, which:++- Are not yet supported by GHC (though [the+proposal](https://github.com/ghc-proposals/ghc-proposals/pull/313) for including+support for them has been accepted).++- Are quite hard to understand.++- Make the library "too powerful" in a sense as it faces+  [a](https://github.com/hasura/eff/issues/13)+  [few](https://github.com/hasura/eff/issues/7)+  [issues](https://github.com/hasura/eff/issues/12) with no clear path towards+  their resolution.++### What about `mtl`?++It's true that its "effects as classes" approach is widely known and used often.++However:++- `mtl` style effects are+  [slow](https://github.com/haskell-effectful/effectful/tree/master/benchmarks/README.md).++- The majority of popular monad transformers (except `ReaderT`) used for effect+  implementations are rife with [subtle+  issues](https://github.com/haskell-effectful/effectful/tree/master/transformers.md).++These are problematic enough that the [ReaderT design+pattern](https://www.fpcomplete.com/blog/2017/06/readert-design-pattern/) was+invented. Its fundamentals are solid, but it's not an effect system.++A solution? Use the `ReaderT` pattern as a base and build around it to make an+extensible effects library! This is where `effectful` comes in. The `Eff` monad+it uses is essentially a `ReaderT` over `IO` on steroids, allowing us to extend+its environment with data types representing effects.++This concept is quite simple, so:++- It's reasonably easy to understand what is going on under the hood.++- The `Eff` monad being a reader allows for seamless interoperability with+  ubiquitous classes such as `MonadBaseControl` and `MonadUnliftIO` and solves+  [issues](https://github.com/haskell-effectful/effectful/tree/master/transformers.md)+  of monad transformers mentioned above.++What is more, the `Eff` monad is concrete, so GHC has many possibilities for+optimization, which results in a very fast code at a default optimization+level. There is no need to mark every function `INLINE` or enable additional+optimization passes, it just works.++### Any downsides?++As always, there's no free lunch. The `Eff` monad doesn't support `NonDet` nor+`Coroutine` effects. However, the `NonDet` effect in existing libraries is+[broken](https://github.com/lexi-lambda/eff/blob/8c4df4bf54faf22456354be18095b14825be5e85/notes/semantics-zoo.md)+and none of the ones with support for higher order effects provide the+`Coroutine` effect, so arguably it's not a big loss.++If you need such capability in your application, there are well established+libraries such as [conduit](https://hackage.haskell.org/package/conduit) or+[list-t](https://hackage.haskell.org/package/list-t) that can be used with+`effectful` without any issues.++### Summary++`effectful` is an extensible effects library that aims to replace "boring"+transformer stacks (which consist of a dozen of newtype'd `ExceptT`, `ReaderT`,+`StateT` and `WriterT` transformers) and their derivatives by providing+equivalent effects with improved semantics, performance and usability (it also+makes it easy to reuse them for your own effects). It doesn't try to make monad+transformers obsolete, so you're free to use it with `ConduitT`, `ContT`,+`ListT` etc. when necessary.++## Package structure++The effect system is split among several libraries:++- The [`effectful-core`](https://hackage.haskell.org/package/effectful-core)+  library contains the core of the effect system along with the basic+  effects. It aims for a small dependency footprint and provides building blocks+  for more advanced effects.++- The [`effectful-plugin`](https://hackage.haskell.org/package/effectful-plugin)+  library provides an optional GHC plugin for improving disambiguation of+  effects (see+  [here](https://github.com/haskell-effectful/effectful/blob/master/effectful-plugin/README.md)+  for more information).++- The [`effectful-th`](https://hackage.haskell.org/package/effectful-th) library+  provides utilities for generating bits of effect-related boilerplate via+  Template Haskell.++- The [`effectful`](https://hackage.haskell.org/package/effectful) library+  re-exports public modules of `effectful-core` and additionally provides most+  features of the `unliftio` library divided into appropriate effects.++## Example++A `Filesystem` effect with two handlers, one that runs in `IO` and another that+uses an in-memory virtual file system can be found+[here](https://github.com/haskell-effectful/effectful/blob/master/effectful/examples/FileSystem.hs).++## Resources++Resources that inspired the rise of this library and had a lot of impact on its+design.++Talks:++* [Effects for Less](https://www.youtube.com/watch?v=0jI-AlWEwYI) by Alexis King.++* [Monad Transformer State](https://www.youtube.com/watch?v=KZIN9f9rI34) by Michael Snoyman.++Blog posts:++* [ReaderT design pattern](https://www.fpcomplete.com/blog/2017/06/readert-design-pattern/) by Michael Snoyman.++* [Exceptions Best Practices](https://www.fpcomplete.com/blog/2016/11/exceptions-best-practices-haskell/) by Michael Snoyman.++----------------------------------------++<div>Icons made by <a href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>
+ effectful-th.cabal view
@@ -0,0 +1,77 @@+cabal-version:      2.4+build-type:         Simple+name:               effectful-th+version:            1.0.0.0+license:            BSD-3-Clause+license-file:       LICENSE+category:           Control+maintainer:         andrzej@rybczak.net+author:             Andrzej Rybczak+synopsis:           Template Haskell utilities for the effectful library.++description: Generate functions for performing operations of dynamically+             dispatched effects via Template Haskell.++extra-source-files:+  CHANGELOG.md+  README.md++tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.3 || ==9.4.1++bug-reports:   https://github.com/haskell-effectful/effectful/issues+source-repository head+  type:     git+  location: https://github.com/haskell-effectful/effectful.git++common language+    ghc-options:        -Wall -Wcompat -Wno-unticked-promoted-constructors++    default-language:   Haskell2010++    default-extensions: BangPatterns+                        ConstraintKinds+                        DataKinds+                        DeriveFunctor+                        DeriveGeneric+                        FlexibleContexts+                        FlexibleInstances+                        GADTs+                        GeneralizedNewtypeDeriving+                        LambdaCase+                        MultiParamTypeClasses+                        NoStarIsType+                        RankNTypes+                        RecordWildCards+                        RoleAnnotations+                        ScopedTypeVariables+                        StandaloneDeriving+                        TupleSections+                        TypeApplications+                        TypeFamilies+                        TypeOperators++library+    import:         language++    build-depends:    base                >= 4.13      && < 5+                    , containers          >= 0.6+                    , effectful           >= 1.0.0.0   && < 1.0.1.0+                    , exceptions          >= 0.10.4+                    , template-haskell    >= 2.15      && < 2.20+                    , th-abstraction      >= 0.4       && < 0.5++    hs-source-dirs:  src++    exposed-modules: Effectful.TH++test-suite th-tests+    import:         language++    build-depends:    base+                    , effectful+                    , effectful-th++    hs-source-dirs: tests++    type:           exitcode-stdio-1.0+    main-is:        ThTests.hs
+ src/Effectful/TH.hs view
@@ -0,0 +1,270 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+-- | Generate functions for performing operations of dynamically dispatched+-- effects via Template Haskell.+module Effectful.TH+  ( makeEffect+  , makeEffect_+  ) where++import Control.Monad+import Data.Char (toLower)+import Data.Foldable (foldl')+import Data.Maybe+import Language.Haskell.TH+import Language.Haskell.TH.Datatype+import Language.Haskell.TH.Datatype.TyVarBndr+import qualified Data.Map.Strict as Map++import Effectful+import Effectful.Dispatch.Dynamic++-- | For an effect data type @E@, @'makeEffect' E@ generates the appropriate+-- instance of 'DispatchOf' as well as functions for performing operations of+-- @E@ by 'send'ing them to the effect handler.+--+-- >>> :{+--   data E :: Effect where+--     Op1 :: Int -> m a -> E m a+--     Op2 :: IOE :> es => Int -> E (Eff es) ()+--     Op3 :: (forall r. m r -> m r) -> E m Int+--   makeEffect ''E+-- :}+--+-- >>> :kind! DispatchOf E+-- DispatchOf E :: Dispatch+-- = 'Dynamic+--+-- >>> :i op1+-- op1 :: (HasCallStack, E :> es) => Int -> Eff es a -> Eff es a+-- ...+--+-- >>> :i op2+-- op2 :: (HasCallStack, E :> es, IOE :> es) => Int -> Eff es ()+-- ...+--+-- >>> :i op3+-- op3 ::+--   (HasCallStack, E :> es) =>+--   (forall r. Eff es r -> Eff es r) -> Eff es Int+-- ...+--+-- The naming rule changes the first uppercase letter in the constructor name to+-- lowercase or removes the @:@ symbol in case of operators. Any fixity+-- annotations defined for the constructors are preserved for the corresponding+-- definitions.+makeEffect :: Name -> Q [Dec]+makeEffect = makeEffectImpl True++-- | Like 'makeEffect', but doesn't generate type signatures. This is useful+-- when you want to attach Haddock documentation to function signatures:+--+-- >>> :{+--   data Noop :: Effect where+--     Noop :: Noop m ()+--   makeEffect_ ''Noop+--   -- | Perform nothing at all.+--   noop :: Noop :> es => Eff es ()+-- :}+--+-- /Note:/ function signatures must be added /after/ the call to 'makeEffect_'.+makeEffect_ :: Name -> Q [Dec]+makeEffect_ = makeEffectImpl False++makeEffectImpl :: Bool -> Name -> Q [Dec]+makeEffectImpl makeSig effName = do+  checkRequiredExtensions+  info <- reifyDatatype effName+  dispatch <- do+    e <- getEff (ConT $ datatypeName info) (datatypeInstTypes info)+    let dispatchE = ConT ''DispatchOf `AppT` e+        dynamic   = PromotedT 'Dynamic+    pure . TySynInstD $ TySynEqn Nothing dispatchE dynamic+  ops <- traverse (makeCon makeSig) (constructorName <$> datatypeCons info)+  pure $ dispatch : concat (reverse ops)+  where+    getEff :: Type -> [Type] -> Q Type+    getEff e = \case+      [m, r]   -> do+        checkKind "the next to last" (ArrowT `AppT` StarT `AppT` StarT) m+        checkKind "the last" StarT r+        pure e+      (v : vs) -> getEff (e `AppT` forgetKind v) vs+      _        -> fail "The effect data type needs at least 2 type parameters"+      where+        forgetKind = \case+          SigT v _ -> v+          ty       -> ty++    checkKind which expected = \case+      SigT (VarT _) k+        | k == expected -> pure ()+        | otherwise -> fail+           $ "Expected " ++ which ++ " type parameter to have a kind "+          ++ pprint expected ++ ", got " ++ pprint k+      -- Weird type, let it through and see what happens.+      _ -> pure ()++-- | Generate a single definition of an effect operation.+makeCon :: Bool -> Name -> Q [Dec]+makeCon makeSig name = do+  fixity <- reifyFixity name+  typ <- reify name >>= \case+    DataConI _ typ _ -> pure typ+    _ -> fail $ "Not a data constructor: " ++ nameBase name++  (actionParams, (effTy, ename, resTy)) <- extractParams typ++  -- The 'ename' can be either:+  --+  -- - A variable for the monad, in which case we need to generate the @es@+  --   variable and substitute it later for 'Eff es'.+  --+  -- - A variable 'es' for the local 'Eff es' if the monad parameter was locally+  --   substituted in the contructor.+  --+  -- For example in the following effect:+  --+  -- data E :: Effect where+  --   E1 :: Int -> E m ()+  --   E2 :: IOE :> es => E (Eff es) ()+  --+  -- Processing 'E1' will yield 'Right m', but 'E2' will yield 'Left es'.+  --+  -- In the first case we need to substitute the variable ourselves in a few+  -- places, but in the second we're good since it was already substituted.+  (esName, maybeMonadName) <- case ename of+    Left  esName    -> pure (esName, Nothing)+    Right monadName -> (, Just monadName) <$> newName "es"++  let fnName = mkName . toSmartConName $ nameBase name+  fnArgs <- traverse (const $ newName "x") actionParams++  let esVar = VarT esName++      substM :: Type -> Type+      substM = case maybeMonadName of+        Just m  -> applySubstitution . Map.singleton m $ ConT ''Eff `AppT` esVar+        Nothing -> id++      (origActionVars, actionCtx) = extractCtx typ+      actionVars = case maybeMonadName of+        Just m  -> filter ((m /=) . tvName) origActionVars+                ++ [kindedTVSpecified esName $ ListT `AppT` ConT ''Effect]+        Nothing -> origActionVars++#if MIN_VERSION_template_haskell(2,17,0)+  -- In GHC >= 9.0 it's possible to generate the following body:+  --+  -- e x1 .. xN = send (E @ty1 .. @tyN x1 .. xN)+  --+  -- because specificities of constructor variables are exposed.+  --+  -- This allows to generate functions for such effects:+  --+  -- type family F ty :: Type+  -- data AmbEff :: Effect where+  --   AmbEff :: Int -> AmbEff m (F ty)+  --+  -- Sadly the version for GHC < 9 will not compile due to ambiguity error.+  let fnBody =+        let tvFlag = \case+              PlainTV  _ flag   -> flag+              KindedTV _ flag _ -> flag++            tyApps = (`mapMaybe` origActionVars) $ \v -> case tvFlag v of+              InferredSpec  -> Nothing+              SpecifiedSpec -> Just $ if maybeMonadName == Just (tvName v)+                                      then ConT ''Eff `AppT` esVar+                                      else VarT (tvName v)++            effCon = if makeSig+              then foldl' AppTypeE (ConE name) tyApps+              else                  ConE name+        in VarE 'send `AppE` foldl' (\f -> AppE f . VarE) effCon fnArgs+#else+  -- In GHC < 9.0, generate the following body:+  --+  -- e :: E v1 .. vN :> es => x1 -> .. -> xK -> E v1 .. vN (Eff es) r+  -- e x1 .. xK = send (E x1 .. xN :: E v1 .. vK (Eff es) r)+  let fnBody =+        let effOp  = foldl' (\f -> AppE f . VarE) (ConE name) fnArgs+            effSig = effTy `AppT` (ConT ''Eff `AppT` esVar) `AppT` substM resTy+        in if makeSig+           then VarE 'send `AppE` SigE effOp effSig+           else VarE 'send `AppE`      effOp+#endif+  let fnSig = ForallT actionVars+        (ConT ''HasCallStack : UInfixT effTy ''(:>) esVar : actionCtx)+        (makeTyp esVar substM resTy actionParams)++  let rest = FunD fnName [Clause (VarP <$> fnArgs) (NormalB fnBody) []]+           : maybeToList ((`InfixD` name) <$> fixity)+  (++ rest) <$> withHaddock name [SigD fnName fnSig | makeSig]++----------------------------------------+-- Helpers++toSmartConName :: String -> String+toSmartConName = \case+  (':' : xs) -> xs+  (x : xs)   -> toLower x : xs+  _          -> error "empty constructor name"++extractCtx :: Type -> ([TyVarBndrSpec], Cxt)+extractCtx = \case+  ForallT vars ctx _ -> (vars, ctx)+  ty                 -> error $ "unexpected type: " ++ show ty++extractParams :: Type -> Q ([Type], (Type, Either Name Name, Type))+extractParams = \case+  ForallT _ _ ty -> extractParams ty+  SigT ty _ -> extractParams ty+  ParensT ty -> extractParams ty+  ArrowT `AppT` a `AppT` ty -> do+    (args, ret) <- extractParams ty+    pure (a : args, ret)+#if MIN_VERSION_template_haskell(2,17,0)+  MulArrowT `AppT` _ `AppT` a `AppT` ty -> do+    (args, ret) <- extractParams ty+    pure (a : args, ret)+#endif+  effTy `AppT` monadTy `AppT` resTy -> case monadTy of+    VarT monadName -> pure ([], (effTy, Right monadName, resTy))+    ConT eff `AppT` VarT esName+      | eff == ''Eff -> pure ([], (effTy, Left esName, resTy))+    ty -> fail $ "Invalid instantiation of the monad parameter: " ++ pprint ty+  ty -> fail $ "Unexpected type: " ++ pprint ty++makeTyp :: Type -> (Type -> Type) -> Type -> [Type] -> Type+makeTyp esVar substM resTy = \case+  []       -> ConT ''Eff `AppT` esVar `AppT` substM resTy+  (p : ps) -> ArrowT `AppT` substM p `AppT` makeTyp esVar substM resTy ps++withHaddock :: Name -> [Dec] -> Q [Dec]+#if MIN_VERSION_template_haskell(2,18,0)+withHaddock name dec = withDecsDoc+  ("Perform the operation '" ++ nameBase name ++ "'.") (pure dec)+#else+withHaddock _ dec = pure dec+#endif++checkRequiredExtensions :: Q ()+checkRequiredExtensions = do+  missing <- filterM (fmap not . isExtEnabled) exts+  let ppMissing = map (\ext -> "{-# LANGUAGE " <> show ext <> " #-}") missing+  unless (null missing) . fail . unlines $+    [ "Generating functions requires additional language extensions.\n"+    , "You can enable them by adding them to the 'default-extensions'"+    , "field in the .cabal file or the following pragmas to the beginning"+    , "of the source file:\n"+    ] ++ ppMissing+  where+    exts = [ FlexibleContexts+           , ScopedTypeVariables+#if MIN_VERSION_template_haskell(2,17,0)+           , TypeApplications+#endif+           , TypeFamilies+           , TypeOperators+           ]
+ tests/ThTests.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+module Main where++import Data.Kind (Type)+import GHC.TypeLits++import Effectful+import Effectful.TH++main :: IO ()+main = pure () -- only compilation tests++data SimpleADT (m :: Type -> Type) (a :: Type)+  = SimpleADTC1 Int+  | SimpleADTC2 String++makeEffect ''SimpleADT++data ADTSyntax1 (m :: Type -> Type) (a :: Type)+  = a ~ Int => ADTSyntax1C String++makeEffect ''ADTSyntax1++data ADTSyntax2 (m :: Type -> Type) (a :: Type)+  = a ~ Int    => ADTSyntax2C1 Int+  | a ~ String => ADTSyntax2C2 String++makeEffect ''ADTSyntax2++data ADTSyntax3 (m :: Type -> Type) (a :: Type)+  = Show a => ADTSyntax3C a++makeEffect ''ADTSyntax3++data GADTSyntax :: Effect where+  GADTSyntaxC1 :: Int -> GADTSyntax m Int+  GADTSyntaxC2 :: String -> GADTSyntax m String+  GADTSyntaxC3 :: IOE :> es => Bool -> GADTSyntax (Eff es) a++makeEffect ''GADTSyntax++data Fields (m :: Type -> Type) (a :: Type)+  = FieldsC { fieldsCF1 :: Int, fieldsCF2 :: String }++makeEffect ''Fields++newtype Newtype1 (m :: Type -> Type) (a :: Type)+  = Newtype1C Int++makeEffect ''Newtype1++newtype Newtype2 :: Effect where+  Newtype2C :: String -> Newtype2 m a++makeEffect ''Newtype2++data Instance = ADTI | GADTI | NTI | MMI++data family Family (s :: Instance) (m :: Type -> Type) a++data instance Family 'ADTI _ _ = ADTIC1 Int | ADTIC2 String+makeEffect 'ADTIC1++data instance Family 'GADTI _ _ where+  GADTIC1 :: Int -> Family 'GADTI m Int+  GADTIC2 :: String -> Family 'GADTI m String+makeEffect 'GADTIC1++newtype instance Family 'NTI _ _ = NTIC Int+makeEffect 'NTIC++data instance Family 'MMI m (_ m) where+  MMIC1 :: f m -> Family 'MMI m (f m)+  MMIC2 :: (forall x. m x -> m (f m)) -> Family 'MMI m (f m)++makeEffect 'MMIC1++data Complex :: Effect where+  Mono            :: Int -> Complex m Bool+  Poly            :: a -> Complex m a+  PolyIn          :: a -> Complex m Bool+  PolyOut         :: Int -> Complex m a+  Lots            :: a -> b -> c -> d -> e -> f -> Complex m ()+  Nested          :: Maybe b -> Complex m (Maybe a)+  MultiNested     :: (Maybe a, [b]) -> Complex m (Maybe a, [b])+  Existential     :: (forall e. e -> Maybe e) -> Complex m a+  LotsNested      :: Maybe a -> [b] -> (c, c) -> Complex m (a, b, c)+  Dict            :: Ord a => a -> Complex m a+  MultiDict       :: (Eq a, Ord b, Enum a, Num c)+                  => a -> b -> c -> Complex m ()+  IndexedMono     :: f 0 -> Complex m Int+  IndexedPoly     :: forall f (n :: Nat) m . f n -> Complex m (f (n + 1))+  IndexedPolyDict :: KnownNat n => f n -> Complex m Int++makeEffect ''Complex++data HOEff :: Effect where+  EffArgMono :: m () -> HOEff m ()+  EffArgPoly :: m a -> HOEff m a+  EffArgComb :: m a -> (m a -> m b) -> HOEff m b+  EffRank2   :: (forall x. m x -> m (Maybe x)) -> HOEff m a++makeEffect ''HOEff++data ComplexEffArgs b c :: Effect where+  EffMono     :: Int -> ComplexEffArgs Int String m Bool+  EffPoly1    :: a -> ComplexEffArgs a b m a+  EffPoly2    :: a -> ComplexEffArgs a (Maybe a) m Bool+  EffPolyFree :: String -> ComplexEffArgs a b m Int+  EffSame1    :: ComplexEffArgs a a m a+  EffSame2    :: ComplexEffArgs b b m a+  EffHO       :: m b -> ComplexEffArgs b Int m String++makeEffect ''ComplexEffArgs++data HKEffArgs f g :: Effect where+  HKRank2 :: (forall x . f x -> g x) -> HKEffArgs f g m a++makeEffect ''HKEffArgs++data ByCon :: Effect where+  ByConA :: Int -> ByCon m String+  ByConB :: Int -> ByCon m String++makeEffect 'ByConA++data ByField :: Effect where+  ByFieldA :: { byFieldAf :: Int } -> ByField m Int+  ByFieldB :: { byFieldBf :: Int } -> ByField m Int++makeEffect 'byFieldAf++type family F ty+data AmbEff :: Effect where+  AmbEff :: Int -> AmbEff m (F ty)++-- This only works in GHC >= 9, otherwise the 'ty' variable is ambiguous.+#if __GLASGOW_HASKELL__ >= 900+makeEffect 'AmbEff+#endif