effectful 2.3.0.0 → 2.3.1.0
raw patch · 39 files changed
+120/−105 lines, 39 filesdep ~basedep ~effectful-coredep ~polysemyPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base, effectful-core, polysemy
API changes (from Hackage documentation)
+ Effectful.FileSystem: XdgState :: XdgDirectory
- Effectful.Concurrent.Async: data Async a
+ Effectful.Concurrent.Async: data () => Async a
- Effectful.Concurrent.Async: data AsyncCancelled
+ Effectful.Concurrent.Async: data () => AsyncCancelled
- Effectful.Concurrent.Async: data ConcException
+ Effectful.Concurrent.Async: data () => ConcException
- Effectful.Concurrent.Async: data ExceptionInLinkedThread
+ Effectful.Concurrent.Async: data () => ExceptionInLinkedThread
- Effectful.Concurrent.Chan: data Chan a
+ Effectful.Concurrent.Chan: data () => Chan a
- Effectful.Concurrent.MVar: data MVar a
+ Effectful.Concurrent.MVar: data () => MVar a
- Effectful.Concurrent.MVar.Strict: data MVar a
+ Effectful.Concurrent.MVar.Strict: data () => MVar a
- Effectful.Concurrent.QSem: data QSem
+ Effectful.Concurrent.QSem: data () => QSem
- Effectful.Concurrent.QSemN: data QSemN
+ Effectful.Concurrent.QSemN: data () => QSemN
- Effectful.Concurrent.STM: data STM a
+ Effectful.Concurrent.STM: data () => STM a
- Effectful.Concurrent.STM: data TBQueue a
+ Effectful.Concurrent.STM: data () => TBQueue a
- Effectful.Concurrent.STM: data TChan a
+ Effectful.Concurrent.STM: data () => TChan a
- Effectful.Concurrent.STM: data TMVar a
+ Effectful.Concurrent.STM: data () => TMVar a
- Effectful.Concurrent.STM: data TQueue a
+ Effectful.Concurrent.STM: data () => TQueue a
- Effectful.Concurrent.STM: data TVar a
+ Effectful.Concurrent.STM: data () => TVar a
- Effectful.FileSystem: data Permissions
+ Effectful.FileSystem: data () => Permissions
- Effectful.FileSystem: data XdgDirectory
+ Effectful.FileSystem: data () => XdgDirectory
- Effectful.FileSystem: data XdgDirectoryList
+ Effectful.FileSystem: data () => XdgDirectoryList
- Effectful.FileSystem.IO: data BufferMode
+ Effectful.FileSystem.IO: data () => BufferMode
- Effectful.FileSystem.IO: data Handle
+ Effectful.FileSystem.IO: data () => Handle
- Effectful.FileSystem.IO: data IOMode
+ Effectful.FileSystem.IO: data () => IOMode
- Effectful.FileSystem.IO: data SeekMode
+ Effectful.FileSystem.IO: data () => SeekMode
- Effectful.Process: data CmdSpec
+ Effectful.Process: data () => CmdSpec
- Effectful.Process: data CreateProcess
+ Effectful.Process: data () => CreateProcess
- Effectful.Process: data ProcessHandle
+ Effectful.Process: data () => ProcessHandle
- Effectful.Process: data StdStream
+ Effectful.Process: data () => StdStream
Files
- CHANGELOG.md +9/−0
- README.md +2/−1
- bench/Concurrency.hs +1/−1
- bench/Countdown.hs +22/−22
- bench/FileSizes.hs +21/−21
- bench/Unlift.hs +2/−2
- effectful.cabal +11/−9
- src/Effectful/Concurrent.hs +2/−2
- src/Effectful/Concurrent/Async.hs +3/−3
- src/Effectful/Concurrent/Chan.hs +1/−1
- src/Effectful/Concurrent/MVar.hs +1/−1
- src/Effectful/Concurrent/MVar/Strict.hs +1/−1
- src/Effectful/Concurrent/QSem.hs +1/−1
- src/Effectful/Concurrent/QSemN.hs +1/−1
- src/Effectful/Concurrent/STM.hs +1/−1
- src/Effectful/Console/ByteString.hs +1/−1
- src/Effectful/Console/ByteString/Lazy.hs +1/−1
- src/Effectful/Environment.hs +1/−1
- src/Effectful/FileSystem.hs +1/−1
- src/Effectful/FileSystem/IO.hs +1/−1
- src/Effectful/FileSystem/IO/ByteString.hs +3/−8
- src/Effectful/FileSystem/IO/ByteString/Builder.hs +2/−3
- src/Effectful/FileSystem/IO/ByteString/Lazy.hs +1/−1
- src/Effectful/FileSystem/IO/File.hs +1/−1
- src/Effectful/Process.hs +1/−1
- src/Effectful/Temporary.hs +1/−1
- src/Effectful/Timeout.hs +1/−1
- tests/AsyncTests.hs +2/−2
- tests/ConcurrencyTests.hs +2/−2
- tests/EnvTests.hs +1/−1
- tests/EnvironmentTests.hs +1/−1
- tests/ErrorTests.hs +9/−0
- tests/NonDetTests.hs +1/−1
- tests/PrimTests.hs +1/−1
- tests/ReaderTests.hs +1/−1
- tests/StateTests.hs +4/−4
- tests/TimeoutTests.hs +1/−1
- tests/UnliftTests.hs +2/−2
- tests/Utils.hs +1/−1
CHANGELOG.md view
@@ -1,3 +1,12 @@+# effectful-2.3.1.0 (2024-06-07)+* Drop support for GHC 8.8.+* Remove inaccurate information from the `Show` instance of `ErrorWrapper`.+* Add `Effectful.Provider.List`, generalization of `Effectful.Provider`.+* Respect `withFrozenCallStack` used by callers of `send`.+* Support exchange of effects between the environment of the handler and the+ local one via `localSeqLend`, `localLend`, `localSeqBorrow` and `localBorrow`+ from `Effectful.Dispatch.Dynamic`.+ # effectful-2.3.0.0 (2023-09-13) * Deprecate `withConcEffToIO`. * Make `withEffToIO` take an explicit unlifting strategy for the sake of
README.md view
@@ -161,7 +161,8 @@ For the examples see the *Introduction* sections of [`Effectful.Dispatch.Dynamic`](https://hackage.haskell.org/package/effectful-core/docs/Effectful-Dispatch-Dynamic.html) and-[`Effectful.Dispatch.Static`](https://hackage.haskell.org/package/effectful-core/docs/Effectful-Dispatch-Static.html).+[`Effectful.Dispatch.Static`](https://hackage.haskell.org/package/effectful-core/docs/Effectful-Dispatch-Static.html)+(when in doubt, start with dynamic dispatch). ## Acknowledgements
bench/Concurrency.hs view
@@ -11,9 +11,9 @@ import Control.Concurrent.Async import Control.Monad-import qualified Effectful.Concurrent.Async as A import Effectful+import Effectful.Concurrent.Async qualified as A import Effectful.Dispatch.Dynamic import Utils
bench/Countdown.hs view
@@ -6,51 +6,51 @@ -- eff #ifdef VERSION_eff-import qualified Control.Effect as L+import Control.Effect qualified as L #endif -- cleff #ifdef VERSION_cleff-import qualified Cleff as C-import qualified Cleff.Reader as C-import qualified Cleff.State as C+import Cleff qualified as C+import Cleff.Reader qualified as C+import Cleff.State qualified as C #endif -- effectful-import qualified Effectful as E-import qualified Effectful.Dispatch.Dynamic as E-import qualified Effectful.Labeled as E-import qualified Effectful.Reader.Static as E-import qualified Effectful.State.Dynamic as ED-import qualified Effectful.State.Static.Local as EL-import qualified Effectful.State.Static.Shared as ES+import Effectful qualified as E+import Effectful.Dispatch.Dynamic qualified as E+import Effectful.Labeled qualified as E+import Effectful.Reader.Static qualified as E+import Effectful.State.Dynamic qualified as ED+import Effectful.State.Static.Local qualified as EL+import Effectful.State.Static.Shared qualified as ES -- freer-simple #ifdef VERSION_freer_simple-import qualified Control.Monad.Freer as FS-import qualified Control.Monad.Freer.Reader as FS-import qualified Control.Monad.Freer.State as FS+import Control.Monad.Freer qualified as FS+import Control.Monad.Freer.Reader qualified as FS+import Control.Monad.Freer.State qualified as FS #endif -- fused-effects #ifdef VERSION_fused_effects-import qualified Control.Algebra as FE-import qualified Control.Carrier.Reader as FE-import qualified Control.Carrier.State.Strict as FE+import Control.Algebra qualified as FE+import Control.Carrier.Reader qualified as FE+import Control.Carrier.State.Strict qualified as FE #endif -- mtl #ifdef VERSION_mtl-import qualified Control.Monad.Reader as M-import qualified Control.Monad.State as M+import Control.Monad.Reader qualified as M+import Control.Monad.State qualified as M import Data.Functor.Identity #endif -- polysemy #ifdef VERSION_polysemy-import qualified Polysemy as P-import qualified Polysemy.Reader as P-import qualified Polysemy.State as P+import Polysemy qualified as P+import Polysemy.Reader qualified as P+import Polysemy.State qualified as P #endif ----------------------------------------
bench/FileSizes.hs view
@@ -7,53 +7,53 @@ import Control.Monad.IO.Class import Data.IORef import Data.Text (Text)+import Data.Text qualified as T import System.Posix-import qualified Data.Text as T -- effectful-import qualified Effectful as E-import qualified Effectful.Dispatch.Dynamic as E-import qualified Effectful.Reader.Static as E-import qualified Effectful.State.Static.Local as E+import Effectful qualified as E+import Effectful.Dispatch.Dynamic qualified as E+import Effectful.Reader.Static qualified as E+import Effectful.State.Static.Local qualified as E -- eff #ifdef VERSION_eff-import qualified Control.Effect as L+import Control.Effect qualified as L #endif -- cleff #ifdef VERSION_cleff-import qualified Cleff as C-import qualified Cleff.Reader as C-import qualified Cleff.State as C+import Cleff qualified as C+import Cleff.Reader qualified as C+import Cleff.State qualified as C #endif -- freer-simple #ifdef VERSION_freer_simple-import qualified Control.Monad.Freer as FS-import qualified Control.Monad.Freer.Reader as FS-import qualified Control.Monad.Freer.State as FS+import Control.Monad.Freer qualified as FS+import Control.Monad.Freer.Reader qualified as FS+import Control.Monad.Freer.State qualified as FS #endif -- fused-effects #ifdef VERSION_fused_effects-import qualified Control.Algebra as FE-import qualified Control.Effect.Sum as FE-import qualified Control.Carrier.Reader as FE-import qualified Control.Carrier.State.Strict as FE+import Control.Algebra qualified as FE+import Control.Effect.Sum qualified as FE+import Control.Carrier.Reader qualified as FE+import Control.Carrier.State.Strict qualified as FE #endif -- mtl #ifdef VERSION_mtl-import qualified Control.Monad.State as M-import qualified Control.Monad.Reader as M+import Control.Monad.State qualified as M+import Control.Monad.Reader qualified as M #endif -- polysemy #ifdef VERSION_polysemy-import qualified Polysemy as P-import qualified Polysemy.Reader as P-import qualified Polysemy.State as P+import Polysemy qualified as P+import Polysemy.Reader qualified as P+import Polysemy.State qualified as P #endif tryGetFileSize :: FilePath -> IO (Maybe Int)
bench/Unlift.hs view
@@ -9,12 +9,12 @@ import Test.Tasty.Bench #endif -import qualified UnliftIO as U+import UnliftIO qualified as U import Effectful+import Effectful.Concurrent.Async qualified as A import Effectful.State.Dynamic import Utils-import qualified Effectful.Concurrent.Async as A unliftBenchmark :: Benchmark unliftBenchmark = bgroup "unlifting"
effectful.cabal view
@@ -1,7 +1,7 @@-cabal-version: 2.4+cabal-version: 3.0 build-type: Simple name: effectful-version: 2.3.0.0+version: 2.3.1.0 license: BSD-3-Clause license-file: LICENSE category: Control@@ -22,8 +22,7 @@ CHANGELOG.md README.md -tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.7 || ==9.6.2- || ==9.8.1+tested-with: GHC == { 8.10.7, 9.0.2, 9.2.8, 9.4.8, 9.6.5, 9.8.2, 9.10.1 } bug-reports: https://github.com/haskell-effectful/effectful/issues source-repository head@@ -36,6 +35,7 @@ common language ghc-options: -Wall -Wcompat -Wno-unticked-promoted-constructors+ -Werror=prepositive-qualified-module default-language: Haskell2010 @@ -48,6 +48,7 @@ FlexibleInstances GADTs GeneralizedNewtypeDeriving+ ImportQualifiedPost LambdaCase MultiParamTypeClasses NoStarIsType@@ -64,11 +65,11 @@ library import: language - build-depends: base >= 4.13 && < 5+ build-depends: base >= 4.14 && < 5 , async >= 2.2.2 , bytestring >= 0.10 , directory >= 1.3.2- , effectful-core >= 2.3.0.0 && < 2.3.1.0+ , effectful-core >= 2.3.1.0 && < 2.3.2.0 , process >= 1.6.9 , time >= 1.9.2@@ -112,6 +113,7 @@ , Effectful.NonDet , Effectful.Prim , Effectful.Provider+ , Effectful.Provider.List , Effectful.Reader.Dynamic , Effectful.Reader.Static , Effectful.State.Dynamic@@ -169,11 +171,11 @@ if impl(ghc < 9.9) build-depends: freer-simple >= 1.2.1.2 - if impl(ghc < 9.9)+ if impl(ghc < 9.11) build-depends: fused-effects >= 1.1.2.2 - if impl(ghc < 9.7)- build-depends: polysemy >= 1.9.1.0+ if impl(ghc < 9.9)+ build-depends: polysemy >= 1.9.1.3 build-depends: base , async
src/Effectful/Concurrent.hs view
@@ -59,13 +59,13 @@ , C.rtsSupportsBoundThreads ) where +import Control.Concurrent qualified as C import Control.Exception (Exception, SomeException) import Data.Bifunctor (second)+import GHC.Conc qualified as GHC import System.Mem.Weak (Weak) import System.Posix.Types (Fd) import UnliftIO.STM (STM)-import qualified Control.Concurrent as C-import qualified GHC.Conc as GHC import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/Async.hs view
@@ -80,9 +80,9 @@ import Control.Exception (Exception, SomeException) import Control.Monad (forever) import Data.Kind (Type)-import qualified Control.Concurrent.Async as A-import qualified UnliftIO.Async as U-import qualified UnliftIO.Internals.Async as I+import Control.Concurrent.Async qualified as A+import UnliftIO.Async qualified as U+import UnliftIO.Internals.Async qualified as I import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/Chan.hs view
@@ -17,7 +17,7 @@ ) where import Control.Concurrent.Chan (Chan)-import qualified Control.Concurrent.Chan as C+import Control.Concurrent.Chan qualified as C import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/MVar.hs view
@@ -29,7 +29,7 @@ import System.Mem.Weak (Weak) import Control.Concurrent.MVar (MVar)-import qualified Control.Concurrent.MVar as M+import Control.Concurrent.MVar qualified as M import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/MVar/Strict.hs view
@@ -30,7 +30,7 @@ import System.Mem.Weak (Weak) import Control.Concurrent.MVar (MVar)-import qualified Control.Concurrent.MVar as M+import Control.Concurrent.MVar qualified as M import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/QSem.hs view
@@ -14,7 +14,7 @@ ) where import Control.Concurrent.QSem (QSem)-import qualified Control.Concurrent.QSem as Q+import Control.Concurrent.QSem qualified as Q import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/QSemN.hs view
@@ -14,7 +14,7 @@ ) where import Control.Concurrent.QSemN (QSemN)-import qualified Control.Concurrent.QSemN as Q+import Control.Concurrent.QSemN qualified as Q import Effectful import Effectful.Concurrent.Effect
src/Effectful/Concurrent/STM.hs view
@@ -90,7 +90,7 @@ ) where import Control.Concurrent.STM (STM, TVar, TMVar, TChan, TQueue, TBQueue)-import qualified Control.Concurrent.STM as STM+import Control.Concurrent.STM qualified as STM import System.Mem.Weak (Weak) import GHC.Natural (Natural)
src/Effectful/Console/ByteString.hs view
@@ -32,7 +32,7 @@ ) import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8+import Data.ByteString.Char8 qualified as BS8 import Effectful import Effectful.Console.Effect
src/Effectful/Console/ByteString/Lazy.hs view
@@ -30,7 +30,7 @@ ) import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy.Char8 as LBS8+import Data.ByteString.Lazy.Char8 qualified as LBS8 import Effectful import Effectful.Console.Effect
src/Effectful/Environment.hs view
@@ -20,7 +20,7 @@ , withProgName ) where -import qualified System.Environment as E+import System.Environment qualified as E import Effectful import Effectful.Dispatch.Static
src/Effectful/FileSystem.hs view
@@ -92,7 +92,7 @@ ) where import Data.Time (UTCTime)-import qualified System.Directory as D+import System.Directory qualified as D import Effectful import Effectful.Dispatch.Static
src/Effectful/FileSystem/IO.hs view
@@ -39,7 +39,7 @@ ) where import System.IO (Handle, IOMode (..))-import qualified System.IO as IO+import System.IO qualified as IO import Effectful import Effectful.Dispatch.Static
src/Effectful/FileSystem/IO/ByteString.hs view
@@ -35,15 +35,10 @@ , hPutStrLn ) where -import Prelude hiding- ( appendFile- , readFile- , writeFile- )- import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as BS8+import Data.ByteString qualified as BS+import Data.ByteString.Char8 qualified as BS8+import Prelude hiding (appendFile, readFile, writeFile) import System.IO (Handle) import Effectful
src/Effectful/FileSystem/IO/ByteString/Builder.hs view
@@ -16,10 +16,9 @@ #endif ) where -import Prelude hiding (writeFile)- import Data.ByteString.Builder (Builder)-import qualified Data.ByteString.Builder as BSB+import Data.ByteString.Builder qualified as BSB+import Prelude hiding (writeFile) import System.IO (Handle) import Effectful
src/Effectful/FileSystem/IO/ByteString/Lazy.hs view
@@ -29,7 +29,7 @@ ) import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy.Char8 as LBS8+import Data.ByteString.Lazy.Char8 qualified as LBS8 import System.IO (Handle) import Effectful
src/Effectful/FileSystem/IO/File.hs view
@@ -15,7 +15,7 @@ import Data.ByteString (ByteString) import System.IO (Handle, IOMode (..))-import qualified UnliftIO.IO.File as U+import UnliftIO.IO.File qualified as U import Effectful import Effectful.Dispatch.Static
src/Effectful/Process.hs view
@@ -51,7 +51,7 @@ import System.Exit (ExitCode) import System.IO (Handle) import System.Posix.Internals (FD)-import qualified System.Process as P+import System.Process qualified as P import Effectful import Effectful.Dispatch.Static
src/Effectful/Temporary.hs view
@@ -13,7 +13,7 @@ ) where import System.IO-import qualified UnliftIO.Temporary as T+import UnliftIO.Temporary qualified as T import Effectful import Effectful.Dispatch.Static
src/Effectful/Timeout.hs view
@@ -9,7 +9,7 @@ , timeout ) where -import qualified System.Timeout as T+import System.Timeout qualified as T import Effectful import Effectful.Dispatch.Static
tests/AsyncTests.hs view
@@ -2,16 +2,16 @@ import Control.Concurrent (threadDelay) import Control.Monad+import Data.Set qualified as S import Test.Tasty import Test.Tasty.HUnit-import qualified Data.Set as S import Effectful import Effectful.Concurrent.Async import Effectful.Error.Static import Effectful.State.Dynamic -import qualified Utils as U+import Utils qualified as U asyncTests :: TestTree asyncTests = testGroup "Async"
tests/ConcurrencyTests.hs view
@@ -2,15 +2,15 @@ import Control.Concurrent (threadDelay) import Control.Monad+import Data.Set qualified as S import Test.Tasty import Test.Tasty.HUnit import UnliftIO-import qualified Data.Set as S import Effectful import Effectful.Error.Static import Effectful.State.Dynamic-import qualified Utils as U+import Utils qualified as U concurrencyTests :: TestTree concurrencyTests = testGroup "Concurrency"
tests/EnvTests.hs view
@@ -12,7 +12,7 @@ import Effectful.Reader.Static import Effectful.Provider import Effectful.State.Static.Local-import qualified Utils as U+import Utils qualified as U envTests :: TestTree envTests = testGroup "Env"
tests/EnvironmentTests.hs view
@@ -6,7 +6,7 @@ import Effectful import Effectful.Environment-import qualified Utils as U+import Utils qualified as U environmentTests :: TestTree environmentTests = testCaseSteps "Environment" $ \step -> do
tests/ErrorTests.hs view
@@ -5,11 +5,13 @@ import Effectful import Effectful.Dispatch.Dynamic+import Effectful.Error.Dynamic qualified as D import Effectful.Error.Static errorTests :: TestTree errorTests = testGroup "Error" [ testCase "different handlers are independent" test_independentHandlers+ , testCase "call stack of dynamic throwError doesn't show internal details" test_dynamicThrowErrorCallStack ] test_independentHandlers :: Assertion@@ -20,6 +22,13 @@ Left (cs, _) -> assertBool "stack trace points to the correct action" $ "outerThrow" == fst (last $ getCallStack cs) Right _ -> assertFailure "error caught by the wrong (inner) handler"++test_dynamicThrowErrorCallStack :: Assertion+test_dynamicThrowErrorCallStack = do+ Left (cs, ()) <- runEff . D.runError @() $ D.throwError ()+ case getCallStack cs of+ [("throwError", _)] -> pure ()+ _ -> assertFailure $ "invalid call stack: " ++ prettyCallStack cs ---------------------------------------- -- Helpers
tests/NonDetTests.hs view
@@ -9,7 +9,7 @@ import Effectful.Reader.Static import Effectful.State.Dynamic -import qualified Utils as U+import Utils qualified as U nonDetTests :: TestTree nonDetTests = testGroup "NonDet"
tests/PrimTests.hs view
@@ -3,7 +3,7 @@ import Data.Primitive.MutVar import Test.Tasty import Test.Tasty.HUnit-import qualified Utils as U+import Utils qualified as U import Effectful import Effectful.Prim
tests/ReaderTests.hs view
@@ -6,7 +6,7 @@ import Effectful import Effectful.Dispatch.Dynamic import Effectful.Reader.Dynamic-import qualified Utils as U+import Utils qualified as U readerTests :: TestTree readerTests = testGroup "Reader"
tests/StateTests.hs view
@@ -1,15 +1,15 @@ module StateTests (stateTests) where +import Control.Exception.Lifted qualified as LE+import Control.Monad.Catch qualified as E import Test.Tasty import Test.Tasty.HUnit-import qualified Control.Monad.Catch as E-import qualified Control.Exception.Lifted as LE-import qualified UnliftIO.Exception as UE+import UnliftIO.Exception qualified as UE import Effectful import Effectful.Dispatch.Dynamic import Effectful.State.Static.Local-import qualified Utils as U+import Utils qualified as U stateTests :: TestTree stateTests = testGroup "State"
tests/TimeoutTests.hs view
@@ -6,7 +6,7 @@ import Effectful import Effectful.Timeout-import qualified Utils as U+import Utils qualified as U timeoutTests :: TestTree timeoutTests = testGroup "Timeout"
tests/UnliftTests.hs view
@@ -3,10 +3,10 @@ import Control.Exception import Test.Tasty import Test.Tasty.HUnit-import qualified UnliftIO.Async as A+import UnliftIO.Async qualified as A import Effectful-import qualified Utils as U+import Utils qualified as U unliftTests :: TestTree unliftTests = testGroup "Unlift"
tests/Utils.hs view
@@ -8,7 +8,7 @@ import Control.Monad.Catch import GHC.Stack-import qualified Test.Tasty.HUnit as T+import Test.Tasty.HUnit qualified as T import Effectful