packages feed

monoidal-plugins (empty) → 0.1.0.0

raw patch · 5 files changed

+181/−0 lines, 5 filesdep +basedep +ghc

Dependencies added: base, ghc

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for monoidal-plugins++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2025, Aaron Allen+++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 the copyright holder nor the names of its+      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+HOLDER 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,3 @@+# monoidal-plugins++A monoidal interface for aggregating GHC plugins
+ monoidal-plugins.cabal view
@@ -0,0 +1,29 @@+cabal-version:      3.0+name:               monoidal-plugins+version:            0.1.0.0+synopsis: A monoidal interface for aggregating GHC plugins+description: A monoidal interface for aggregating GHC plugins into a single plugin+category: Development+license:            BSD-3-Clause+license-file:       LICENSE+author:             Aaron Allen+maintainer:         aaronallen8455@gmail.com+copyright:          2025 Aaron Allen+build-type:         Simple+extra-doc-files:    CHANGELOG.md+                    README.md++source-repository head+  type: git+  location: https://github.com/aaronallen8455/monoidal-plugins++common warnings+    ghc-options: -Wall++library+    import:           warnings+    exposed-modules:  MonoidalPlugins+    build-depends:    base < 5,+                      ghc >= 9.6 && < 9.13+    hs-source-dirs:   src+    default-language: GHC2021
+ src/MonoidalPlugins.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE CPP #-}+module MonoidalPlugins+  ( MonoidalPlugin(..)+  , foldPlugins+  ) where++import           Control.Monad+import           Control.Monad.IO.Class+import           Data.Coerce+import           Data.Foldable+import           Data.IORef+import           GHC.Driver.Plugins+#if MIN_VERSION_ghc(9,8,0)+import           GHC.Tc.Errors.Hole.Plugin+#else+import           GHC.Tc.Errors.Hole.FitTypes+#endif+import qualified GHC.Tc.Types as Tc++foldPlugins+  :: forall f. (Foldable f, Coercible (f Plugin) (f MonoidalPlugin))+  => f Plugin -> Plugin+foldPlugins = coerce . fold @f @MonoidalPlugin . coerce++newtype MonoidalPlugin = MonoidalPlugin { unMonoidalPlugin :: Plugin }++instance Semigroup MonoidalPlugin where+  MonoidalPlugin a <> MonoidalPlugin b = MonoidalPlugin Plugin+    { installCoreToDos = \opts ->+        installCoreToDos a opts >=> installCoreToDos b opts+    , tcPlugin = \opts -> coerce $+        (coerce $ tcPlugin a opts :: Maybe SGTcPlugin)+        <> coerce (tcPlugin b opts)+    , defaultingPlugin = \opts -> coerce $+        (coerce $ defaultingPlugin a opts :: Maybe SGDefaultingPlugin)+        <> coerce (defaultingPlugin b opts)+    , holeFitPlugin = \opts -> coerce $+        (coerce $ holeFitPlugin a opts :: Maybe SGHoleFitPlugin)+        <> coerce (holeFitPlugin b opts)+    , driverPlugin = \opts -> driverPlugin a opts >=> driverPlugin b opts+#if MIN_VERSION_ghc(9,10,0)+    , latePlugin = \hscEnv opts -> latePlugin a hscEnv opts >=> latePlugin b hscEnv opts+#endif+    , pluginRecompile = \opts ->+        pluginRecompile a opts <> pluginRecompile b opts+    , parsedResultAction = \opts modSum ->+        parsedResultAction a opts modSum >=> parsedResultAction b opts modSum+    , renamedResultAction = \opts gblEnv ->+        renamedResultAction a opts gblEnv >=> uncurry (renamedResultAction b opts)+    , typeCheckResultAction = \opts modSum ->+        typeCheckResultAction a opts modSum >=> typeCheckResultAction b opts modSum+    , spliceRunAction = \opts ->+        spliceRunAction a opts >=> spliceRunAction b opts+    , interfaceLoadAction = \opts ->+        interfaceLoadAction a opts >=> interfaceLoadAction b opts+    }++instance Monoid MonoidalPlugin where+  mempty = MonoidalPlugin defaultPlugin { pluginRecompile = mempty }++newtype SGHoleFitPlugin = SGHoleFitPlugin HoleFitPluginR++instance Semigroup SGHoleFitPlugin where+  SGHoleFitPlugin (HoleFitPluginR initA runA stopA)+    <> SGHoleFitPlugin (HoleFitPluginR initB runB stopB) =+    SGHoleFitPlugin HoleFitPluginR+    { hfPluginInit = do+        r1 <- initA+        r2 <- initB+        liftIO $ newIORef (r1, r2)+    , hfPluginRun = \ref ->+        HoleFitPlugin+          { candPlugin = \hole xs -> do+              (r1, r2) <- liftIO $ readIORef ref+              candPlugin (runA r1) hole xs >>= candPlugin (runB r2) hole+          , fitPlugin = \hole xs -> do+              (r1, r2) <- liftIO $ readIORef ref+              fitPlugin (runA r1) hole xs >>= fitPlugin (runB r2) hole+          }+    , hfPluginStop = \ref -> do+        (r1, r2) <- liftIO $ readIORef ref+        stopA r1+        stopB r2+    }++newtype SGDefaultingPlugin = SGDefaultingPlugin Tc.DefaultingPlugin++instance Semigroup SGDefaultingPlugin where+  SGDefaultingPlugin (Tc.DefaultingPlugin initA runA stopA)+    <> SGDefaultingPlugin (Tc.DefaultingPlugin initB runB stopB) =+    SGDefaultingPlugin Tc.DefaultingPlugin+    { Tc.dePluginInit = (,) <$> initA <*> initB+    , Tc.dePluginRun = \(s1, s2) wc -> do+        (<>) <$> runA s1 wc <*> runB s2 wc+    , Tc.dePluginStop = \(s1, s2) -> stopA s1 >> stopB s2+    }++newtype SGTcPlugin = SGTcPlugin Tc.TcPlugin++instance Semigroup SGTcPlugin where+  SGTcPlugin (Tc.TcPlugin initA solveA rewriteA stopA)+    <> SGTcPlugin (Tc.TcPlugin initB solveB rewriteB stopB) =+    SGTcPlugin Tc.TcPlugin+    { Tc.tcPluginInit = (,) <$> initA <*> initB+    , Tc.tcPluginSolve = \(s1, s2) evBinds givens wanteds -> do+        r1 <- solveA s1 evBinds givens wanteds+        r2 <- solveB s2 evBinds givens wanteds+        pure Tc.TcPluginSolveResult+          { Tc.tcPluginInsolubleCts = Tc.tcPluginInsolubleCts r1 <> Tc.tcPluginInsolubleCts r2+          , Tc.tcPluginSolvedCts = Tc.tcPluginSolvedCts r1 <> Tc.tcPluginSolvedCts r2+          , Tc.tcPluginNewCts = Tc.tcPluginNewCts r1 <> Tc.tcPluginNewCts r2+          }+    , Tc.tcPluginRewrite = \(s1, s2) -> rewriteA s1 <> rewriteB s2+    , Tc.tcPluginStop = \(s1, s2) -> stopA s1 >> stopB s2+    }