### EffectHandler Example Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/types.md An example demonstrating an EffectHandler for a FileSystem effect, mapping ReadFile operations to IO actions. ```haskell data FileSystem :: Effect where ReadFile :: FilePath -> FileSystem m String handler :: EffectHandler FileSystem es handler = \case ReadFile path -> liftIO $ readFile path ``` -------------------------------- ### SeqUnlift Strategy Example Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Demonstrates the SeqUnlift strategy for sequential execution on the same thread. This strategy will fail if used from different threads. ```haskell SeqUnlift :: Persistence -> Limit -> UnliftStrategy ``` ```haskell withUnliftStrategy (SeqUnlift Persistent Unlimited) $ do -- Operations run sequentially on same thread ``` -------------------------------- ### Example: Creating a Custom Effect (Dynamic Dispatch) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/dispatching.md Demonstrates defining a custom FileSystem effect and running it with an IO-based handler using dynamic dispatch. ```APIDOC ### Example: Creating a Custom Effect ```haskell import Effectful import Effectful.Dispatch.Dynamic -- Define the effect data FileSystem :: Effect where ReadFile :: FilePath -> FileSystem m String WriteFile :: FilePath -> String -> FileSystem m () type instance DispatchOf FileSystem = Dynamic -- Create operation functions readFile :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es String readFile path = send (ReadFile path) writeFile :: (HasCallStack, FileSystem :> es) => FilePath -> String -> Eff es () writeFile path content = send (WriteFile path content) -- Create an IO-based handler runFileSystemIO :: (IOE :> es) => Eff (FileSystem : es) a -> Eff es a runFileSystemIO = interpret $ \_ -> \case ReadFile path -> liftIO (Prelude.readFile path) WriteFile path content -> liftIO (Prelude.writeFile path content) -- Use it main :: IO () main = runEff $ do runFileSystemIO $ do writeFile "test.txt" "Hello" content <- readFile "test.txt" liftIO $ print content ``` ``` -------------------------------- ### StaticRep Example for Reader Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/types.md An example demonstrating the StaticRep type family for a Reader effect. ```haskell data Reader (r :: Type) :: Effect type instance StaticRep (Reader r) = Reader r ``` -------------------------------- ### Example of Effect Presence Constraint Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/types.md An example showing how to use the `:>` constraint to ensure a Reader effect is available. ```haskell readEnv :: Reader String :> es => Eff es String readEnv = ask ``` -------------------------------- ### Example: Static Reader Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/dispatching.md Demonstrates creating and using a static Reader effect, showing how to run it, ask for the current value, and modify it locally. ```APIDOC ### Example: Static Reader Effect ```haskell import Effectful import Effectful.Dispatch.Static import Data.Kind -- Define the effect data Reader (r :: Type) :: Effect type instance DispatchOf (Reader r) = Static NoSideEffects newtype instance StaticRep (Reader r) = Reader r -- Handler runReader :: HasCallStack => r -> Eff (Reader r : es) a -> Eff es a runReader r = evalStaticRep (Reader r) -- Operations ask :: (HasCallStack, Reader r :> es) => Eff es r ask = do Reader r <- getStaticRep pure r local :: (HasCallStack, Reader r :> es) => (r -> r) -> Eff es a -> Eff es a local f = localStaticRep $ \(Reader r) -> Reader (f r) -- Usage main :: IO () main = runEff $ do runReader "Hello" $ do greeting <- ask liftIO $ putStrLn greeting ``` ``` -------------------------------- ### Recommended Core Effects Import Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Import these core effects for general use. Ensure you have the necessary dependencies installed. ```haskell import Effectful import Effectful.Reader.Static import Effectful.State.Static.Local import Effectful.Error.Static ``` -------------------------------- ### Example: Custom Dynamic FileSystem Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/dispatching.md Demonstrates creating a custom FileSystem effect with dynamic dispatch. It includes defining the effect, creating operation functions, implementing an IO-based handler, and using the effect within an Eff computation. ```haskell import Effectful import Effectful.Dispatch.Dynamic -- Define the effect data FileSystem :: Effect where ReadFile :: FilePath -> FileSystem m String WriteFile :: FilePath -> String -> FileSystem m () type instance DispatchOf FileSystem = Dynamic -- Create operation functions readFile :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es String readFile path = send (ReadFile path) writeFile :: (HasCallStack, FileSystem :> es) => FilePath -> String -> Eff es () writeFile path content = send (WriteFile path content) -- Create an IO-based handler runFileSystemIO :: (IOE :> es) => Eff (FileSystem : es) a -> Eff es a runFileSystemIO = interpret $ \_ -> \case ReadFile path -> liftIO (Prelude.readFile path) WriteFile path content -> liftIO (Prelude.writeFile path content) -- Use it main :: IO () main = runEff $ do runFileSystemIO $ do writeFile "test.txt" "Hello" content <- readFile "test.txt" liftIO $ print content ``` -------------------------------- ### Run Environment Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md This example demonstrates how to run the Environment effect and access environment variables and command-line arguments. It requires importing Effectful and Effectful.Environment. ```haskell import Effectful import Effectful.Environment main :: IO () main = runEff $ runEnvironment $ do home <- getEnv "HOME" args <- getArgs liftIO $ putStrLn $ "Home: " ++ home ``` -------------------------------- ### Basic MVar Usage Example Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/concurrent-effects.md Illustrates the basic usage of `MVar` for mutable state management. This example creates an MVar, increments its value, and then reads the updated value. Requires `Effectful` and `Effectful.Concurrent.MVar`. ```haskell import Effectful import Effectful.Concurrent.MVar main :: IO () main = runEff $ runConcurrent $ do var <- newMVar (0 :: Int) modifyMVar_ var $ v -> pure (v + 1) value <- readMVar var liftIO $ print value -- 1 ``` -------------------------------- ### Configure Reader and State Effects Statically Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Demonstrates configuring static effects like Reader and State via type parameters at setup time. The Reader effect is configured with an environment string, and the State effect with an initial integer value. ```haskell import Effectful.Reader.Static import Effectful.State.Static.Local -- Configuration via type parameters main :: IO () main = runEff $ do runReader "environment" $ -- Reader config: the environment value evalState 0 $ -- State config: initial state value do env <- ask s <- get liftIO $ putStrLn $ env ++ ": " ++ show s ``` -------------------------------- ### Get Temporary Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path to the system's temporary directory. Requires the FileSystem effect. ```haskell getTemporaryDirectory :: (HasCallStack, FileSystem :> es) => Eff es FilePath ``` -------------------------------- ### Concurrent Unlifting with IO Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/eff-monad.md This example uses `unliftStrategy ConcUnliftIO` to obtain a function that can concurrently unlift Eff computations to IO. It then uses `async` to run two IO actions concurrently and `wait` to ensure they complete. ```haskell import Effectful import Control.Concurrent.Async main :: IO () main = runEff $ do unlift <- unliftStrategy ConcUnliftIO liftIO $ do r1 <- async (unlift $ liftIO $ putStrLn "Async 1") r2 <- async (unlift $ liftIO $ putStrLn "Async 2") wait r1 wait r2 ``` -------------------------------- ### Get App User Data Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path for application-specific user data. Requires the FileSystem effect. ```haskell getAppUserDataDirectory :: (HasCallStack, FileSystem :> es) => String -> Eff es FilePath ``` -------------------------------- ### Get Home Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path to the user's home directory. This operation requires the FileSystem effect. ```haskell getHomeDirectory :: (HasCallStack, FileSystem :> es) => Eff es FilePath ``` -------------------------------- ### Get XDG Directories List Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves a list of paths for specified XDG directories. Requires the FileSystem effect. ```haskell getXdgDirectoryList :: (HasCallStack, FileSystem :> es) => XdgDirectoryList -> Eff es [FilePath] ``` -------------------------------- ### Writer Effect (Static Local) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/basic-effects.md Example usage of the static local writer effect for accumulating output. ```APIDOC ## Writer Effect (Static Local) Example ### Description This example demonstrates how to use the static local writer effect to accumulate string outputs. ### Usage Import `Effectful.Writer.Static.Local` and use `runWriter` to execute computations that produce output. ### Code Example ```haskell import Effectful import Effectful.Writer.Static.Local main :: IO () main = runEff $ do ((), output) <- runWriter $ do tell "Hello " tell "World" liftIO $ putStrLn output -- "Hello World" ``` ``` -------------------------------- ### Get File Size Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the size of a file in bytes. Requires the FileSystem effect. ```haskell getFileSize :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es Integer ``` -------------------------------- ### Example: Static Reader Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/dispatching.md Illustrates a static Reader effect for passing read-only data. It shows defining the effect, its static representation, handler, and operations like 'ask' and 'local'. ```haskell import Effectful import Effectful.Dispatch.Static import Data.Kind -- Define the effect data Reader (r :: Type) :: Effect type instance DispatchOf (Reader r) = Static NoSideEffects newtype instance StaticRep (Reader r) = Reader r -- Handler runReader :: HasCallStack => r -> Eff (Reader r : es) a -> Eff es a runReader r = evalStaticRep (Reader r) -- Operations ask :: (HasCallStack, Reader r :> es) => Eff es r ask = do Reader r <- getStaticRep pure r local :: (HasCallStack, Reader r :> es) => (r -> r) -> Eff es a -> Eff es a local f = localStaticRep $ \(Reader r) -> Reader (f r) -- Usage main :: IO () main = runEff $ do runReader "Hello" $ do greeting <- ask liftIO $ putStrLn greeting ``` -------------------------------- ### Get User Documents Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path to the user's documents directory. This operation requires the FileSystem effect. ```haskell getUserDocumentsDirectory :: (HasCallStack, FileSystem :> es) => Eff es FilePath ``` -------------------------------- ### Example Usage of Labeled State Effects Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/advanced-effects.md Demonstrates using multiple labeled State effects within an effectful computation. Requires importing specific labeled effect modules and using type-level labels with effect operations. ```Haskell import Effectful import Effectful.Labeled import Effectful.State.Static.Local prog :: (Labeled "count" (State Int) :> es, Labeled "name" (State String) :> es) => Eff es () prog = do modify @"count" (+ 1) modify @"name" (++ "!") main :: IO () main = runEff $ do evalState 0 . evalState "Hi" $ zoom @"count" . zoom @"name" prog ``` -------------------------------- ### Get Current Working Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path of the current working directory. This operation requires the FileSystem effect. ```haskell getCurrentDirectory :: (HasCallStack, FileSystem :> es) => Eff es FilePath ``` -------------------------------- ### Get XDG Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves the path for a specified XDG directory (e.g., config, data). Requires the FileSystem effect. ```haskell getXdgDirectory :: (HasCallStack, FileSystem :> es) => XdgDirectory -> Eff es FilePath ``` -------------------------------- ### Get Directory Contents Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Retrieves all entries within a directory, including hidden files and subdirectories. This function requires the FileSystem effect. ```haskell getDirectoryContents :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es [FilePath] ``` -------------------------------- ### Static Reader Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Effectful.Reader.Static provides immutable, thread-local environment access. Use 'runReader' to start, 'withReader' to modify, and 'ask'/'asks' to retrieve environment values. ```haskell module Effectful.Reader.Static ``` -------------------------------- ### Modify State and Print Current Value Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/basic-effects.md Shows how to modify a mutable state and then print its current value using the State effect. This example uses `modify` to increment the state and `get` to retrieve it. ```haskell import Effectful import Effectful.State.Static.Local counter :: State Int :> es => Eff es () counter = do modify (+ 1) get >>= liftIO . print main :: IO () main = runEff $ do execState 0 $ do counter counter counter ``` -------------------------------- ### Application Startup with Configured Concurrency Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Illustrates setting up an application with a globally applied UnliftStrategy based on environment configuration. It reads the 'NUM_WORKERS' environment variable or defaults to a runtime-suggested CPU count. ```haskell -- At application startup startApp :: IO () startApp = runEff $ do -- Read configuration numWorkers <- runEnvironment $ do workers <- lookupEnv "NUM_WORKERS" pure $ case workers of Just n -> Limited (read n) Nothing -> Limited (runtime_suggested_cpus) -- Apply globally for entire application withUnliftStrategy (ConcUnliftIO Persistent numWorkers) $ do -- Your application code here pure () ``` -------------------------------- ### Run Writer Effect with Static Local Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/basic-effects.md Demonstrates how to use the static local Writer effect to accumulate and print output. Requires importing Effectful and Effectful.Writer.Static.Local. ```haskell import Effectful import Effectful.Writer.Static.Local main :: IO () main = runEff $ do ((), output) <- runWriter $ do tell "Hello " tell "World" liftIO $ putStrLn output -- "Hello World" ``` -------------------------------- ### Create Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Creates a new directory at the specified path. Requires the FileSystem effect to be available. ```haskell createDirectory :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es () ``` -------------------------------- ### Create Directory If Missing Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Creates a directory at the specified path, including any necessary parent directories. The first argument determines whether to create parent directories. ```haskell createDirectoryIfMissing :: (HasCallStack, FileSystem :> es) => Bool -> FilePath -> Eff es () ``` -------------------------------- ### ConcUnliftIO Strategy Configuration Options Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Illustrates various configurations for the ConcUnliftIO strategy, balancing concurrency, state persistence, and resource limits. ```haskell ConcUnliftIO :: Persistence -> Limit -> UnliftStrategy ``` ```haskell - ConcUnliftIO Persistent Unlimited - Full concurrency, persistent state - ConcUnliftIO Persistent (Limited 4) - Max 4 concurrent, persistent state - ConcUnliftIO Ephemeral Unlimited - Full concurrency, isolated state - ConcUnliftIO Ephemeral (Limited 8) - Max 8 concurrent, isolated state ``` -------------------------------- ### Recommended IO Effects Import Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Import these modules for file system and environment access when working with IO effects. ```haskell import Effectful.FileSystem import Effectful.Environment ``` -------------------------------- ### Run Reader Effect with Initial Environment Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/basic-effects.md Demonstrates how to run a Reader effect with an initial environment value. This is useful for providing read-only context to computations. ```haskell import Effectful import Effectful.Reader.Static main :: IO () main = runEff $ do runReader "Hello, World" $ do greeting <- ask liftIO $ putStrLn greeting ``` -------------------------------- ### Handle Pattern with IOException Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Demonstrates the 'Handle Pattern' by catching a specific exception (IOException) and providing a recovery action. ```haskell import Effectful import Effectful.Exception main :: IO () main = runEff $ do result <- handle (\(e :: IOException) -> pure "") $ liftIO $ readFile "missing.txt" liftIO $ putStrLn $ "Content: " ++ result ``` -------------------------------- ### Get Current Unlift Strategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Retrieves the current unlift strategy configured for the effectful computation. Use this to inspect the active strategy. ```haskell unliftStrategy :: IOE :> es => Eff es UnliftStrategy ``` ```haskell main :: IO () main = runEff $ do strategy <- unliftStrategy liftIO $ putStrLn $ "Current strategy: " ++ show strategy ``` -------------------------------- ### Simulate Environment Variable Configuration Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Reads environment variables to construct an UnliftStrategy. Use this to dynamically configure concurrency limits based on the execution environment. ```haskell import Effectful import Effectful.Environment makeStrategyFromEnv :: Environment :> es => Eff es UnliftStrategy makeStrategyFromEnv = do maxConcurrent <- lookupEnv "MAX_CONCURRENT" let limit = case maxConcurrent of Just n -> Limited (read n) Nothing -> Unlimited pure $ ConcUnliftIO Persistent limit main :: IO () main = runEff $ runEnvironment $ do strategy <- makeStrategyFromEnv withUnliftStrategy strategy $ do -- Your concurrent operations here liftIO $ putStrLn "Running with configured strategy" ``` -------------------------------- ### Code with explicit type annotation Source: https://github.com/haskell-effectful/effectful/blob/master/effectful-plugin/README.md This version of the code explicitly annotates the type for 'get' to resolve ambiguity, which the effectful-plugin aims to eliminate. ```haskell action :: (State Int :> es, State String :> es) => Eff es () action = do x <- get @Int put (x + 1) ``` -------------------------------- ### Running a Pure Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/index.md Demonstrates how to run a pure computation using the Effectful library. This is useful for computations that do not involve any side effects. ```haskell import Effectful -- Pure computation result = runPureEff $ do pure 42 ``` -------------------------------- ### withEffToIO Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/eff-monad.md Provides a concurrent unlifting strategy for Eff computations to IO. This allows multiple Eff computations to be unlifted to IO concurrently, which can improve performance for independent operations. ```APIDOC ## Function: withEffToIO ### Description Concurrent unlifting. ### Signature `withEffToIO :: IOE :> es => (forall a. Eff es a -> IO a) -> Eff es b -> Eff es b` ``` -------------------------------- ### Recommended Concurrency Import Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Import this module if your application requires concurrency features like asynchronous operations. ```haskell import Effectful.Concurrent.Async ``` -------------------------------- ### Local Static State Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Effectful.State.Static.Local manages thread-local mutable state with exception semantics. Use 'runState', 'get', 'put', and 'modify' for state manipulation. ```haskell module Effectful.State.Static.Local ``` -------------------------------- ### With Current Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Temporarily changes the current working directory to a specified path, executes an action, and then restores the original directory. Requires the FileSystem effect. ```haskell withCurrentDirectory :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es a -> Eff es a ``` -------------------------------- ### Exception Handling with Try Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/exceptions-and-control.md Demonstrates how to use the `try` function to catch specific exceptions, such as `IOException`, during an effectful computation. The result is handled using a `case` statement to differentiate between success and failure. ```haskell import Effectful import Effectful.Exception main :: IO () main = runEff $ do result <- try @IOException $ do liftIO $ readFile "missing.txt" case result of Left e -> liftIO $ putStrLn $ "Error: " ++ show e Right content -> liftIO $ putStrLn content ``` -------------------------------- ### Using Reader and State Effects Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/index.md Illustrates the usage of static Reader and State effects within an Effectful computation. The `prog` function requires a String environment and modifies an Int state. The `main` function sets up the environment and initial state using `runReader` and `evalState`. ```haskell import Effectful import Effectful.Reader.Static import Effectful.State.Static.Local prog :: (Reader String :> es, State Int :> es) => Eff es () prog = do env <- ask modify (+ 1) main = runEff $ runReader "MyEnv" $ evalState 0 prog ``` -------------------------------- ### Catching errors in ExceptT and StateT Source: https://github.com/haskell-effectful/effectful/blob/master/transformers.md The behavior of `catchError` within `ExceptT` and `StateT` is dependent on the order of the transformer stack. This example demonstrates how rearranging the stack can alter the final state and result. ```haskell #{-# LANGUAGE FlexibleContexts #-} import Control.Monad.Except import Control.Monad.State test :: (MonadError String m, MonadState Int m) => m () test = (modify (+1) >> throwError "oops") `catchError` \_ -> modify (+2) ``` ```haskell main :: IO () main = do putStrLn $ "1. StateT Int (ExceptT IO)" putStrLn . show =<< (runExceptT . (`runStateT` (0::Int)) $ test) putStrLn $ "2. ExceptT (StateT Int IO)" putStrLn . show =<< ((`runStateT` (0::Int)) . runExceptT $ test) ``` -------------------------------- ### withSeqEffToIO Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/eff-monad.md Provides a sequential unlifting strategy for Eff computations to IO. This ensures that only one Eff computation is unlifted to IO at a time, which can be important for managing state or resources that cannot be accessed concurrently. ```APIDOC ## Function: withSeqEffToIO ### Description Sequential unlifting. ### Signature `withSeqEffToIO :: IOE :> es => (forall a. Eff es a -> IO a) -> Eff es b -> Eff es b` ``` -------------------------------- ### Bracket Pattern for Resource Management Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/exceptions-and-control.md Demonstrates the use of the bracket pattern for safely opening and closing resources like files. Ensures that `closeFile` is called even if an exception occurs during file processing. ```haskell import Effectful import Effectful.Exception openFile :: FilePath -> Eff es Handle closeFile :: Handle -> Eff es () main :: IO () main = runEff $ do bracket (openFile "test.txt") closeFile (\h -> do content <- readFromHandle h liftIO $ putStrLn content) ``` -------------------------------- ### Recommended Exception Handling Import Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Import this module for exception handling capabilities within the effectful framework. ```haskell import Effectful.Exception ``` -------------------------------- ### Configure Dynamic Logger Effect with Options Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Shows how to configure a dynamic effect (Logger) using handler-specific options. The `runLoggerWithConfig` function takes a `LoggerConfig` to set the log level and prefix. ```haskell import Effectful.Dispatch.Dynamic data Logger :: Effect where Log :: String -> Logger m () data LoggerConfig = LoggerConfig { logLevel :: Int, logPrefix :: String } runLoggerWithConfig :: LoggerConfig -> Eff (Logger : es) a -> Eff es a runLoggerWithConfig config = interpret $ \_ -> \case Log msg -> liftIO $ putStrLn $ logPrefix config ++ ": " ++ msg ``` -------------------------------- ### Run Reader Effect in IO Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/README.md Demonstrates how to run an Eff computation with the Reader effect in an IO context. Requires importing Effectful and Effectful.Reader.Static. ```haskell import Effectful import Effectful.Reader.Static main :: IO () main = runEff $ runReader "env" $ do value <- ask liftIO $ print value ``` -------------------------------- ### Constant space execution with lazy WriterT and list Source: https://github.com/haskell-effectful/effectful/blob/master/transformers.md When using the lazy `WriterT` with a monad whose bind is lazy (e.g., `Identity`) and a monoid that can be produced and consumed lazily (e.g., `[a]`), constant space execution is achieved. This example demonstrates efficient processing of a large list. ```haskell import Control.Monad.Trans.Writer.Lazy import Data.Foldable main :: IO () main = do let xs = execWriter $ forM_ [1..1000000::Int] $ \n -> tell [n] putStrLn . show $ sum xs ``` -------------------------------- ### Space leak with lazy WriterT and non-lazy monad bind Source: https://github.com/haskell-effectful/effectful/blob/master/transformers.md If the underlying monad's bind operation is not lazy (e.g., `IO`), using `WriterT` can lead to space leaks, even if the monoid is lazy. This example shows the memory consumption when `WriterT` is used with `IO` and `pure ()`. ```haskell import Control.Monad.Trans.Writer.Lazy import Data.Foldable main :: IO () main = execWriterT $ forM_ [1..1000000::Int] $ \_ -> pure () ``` -------------------------------- ### withUnliftStrategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/eff-monad.md Runs a computation with a specified unlift strategy. This function sets up the environment for unlifting Eff computations to IO according to the given strategy, ensuring proper exception handling and resource management. ```APIDOC ## Function: withUnliftStrategy ### Description Run with unlift strategy. ### Signature `withUnliftStrategy :: IOE :> es => UnliftStrategy -> ((Eff es a -> IO a) -> IO b) -> Eff es b` ``` -------------------------------- ### Space leak with lazy WriterT and non-lazy monoid Source: https://github.com/haskell-effectful/effectful/blob/master/transformers.md Using `WriterT` with a monoid that cannot be produced or consumed lazily (e.g., `Sum Int`), even if the underlying monad's bind is lazy, can result in space leaks. This example illustrates the memory usage when `tell`ing `Sum Int` values. ```haskell import Control.Monad.Trans.Writer.Lazy import Data.Foldable import Data.Monoid main :: IO () main = do let Sum xs = execWriter $ forM_ [1..1000000::Int] $ \n -> tell $ Sum n putStrLn $ show xs ``` -------------------------------- ### Sequential Unlift Strategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/advanced-effects.md Defines `withSeqEffToIO` for sequentially converting effectful computations to IO, ensuring proper state handling. Requires the `IOE` effect to be present in the environment. ```Haskell withSeqEffToIO :: IOE :> es => (forall a. Eff es a -> IO a) -> Eff es b -> Eff es b ``` -------------------------------- ### Resource Management with ExceptT and onException Source: https://github.com/haskell-effectful/effectful/blob/master/transformers.md Demonstrates how `withResource` fails to release resources when an `ExceptT`-specific error is thrown, due to `onException` not capturing transformer errors. This highlights a subtle bug that can lead to resource leaks. ```haskell {-# LANGUAGE TypeApplications #} import Control.Monad.Catch import Control.Monad.Except import Control.Monad.IO.Class data Resource = Resource acquireResource :: MonadIO m => m Resource acquireResource = do liftIO $ putStrLn "acquireResource" pure Resource releaseResourceOnSuccess :: MonadIO m => Resource -> m () releaseResourceOnSuccess _ = liftIO $ putStrLn "releaseResourceOnSuccess" releaseResourceOnFailure :: MonadIO m => Resource -> m () releaseResourceOnFailure _ = liftIO $ putStrLn "releaseResourceOnFailure" withResource :: (MonadMask m, MonadIO m) => (Resource -> m a) -> m a withResource action = mask $ \unmask -> do r <- acquireResource a <- unmask (action r) `onException` do releaseResourceOnFailure r releaseResourceOnSuccess r pure a main :: IO () main = do putStrLn "1. IO - no exception" test . withResource $ \Resource -> pure () putStrLn "2. IO - exception" test . withResource $ \Resource -> error "oops" putStrLn "3. ExceptT IO - no exception" test . runExceptT @String . withResource $ \Resource -> pure () putStrLn "4. ExceptT IO - exception" test . runExceptT @String . withResource $ \Resource -> error "oops" putStrLn "4. ExceptT IO - error" test . runExceptT @String . withResource $ \Resource -> throwError "oops" where test :: IO a -> IO () test = void . try @_ @SomeException ``` -------------------------------- ### SeqForkUnlift Strategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Uses the SeqForkUnlift strategy for sequential execution that clones the environment for each call, enabling safe use across different threads. Best for operations needing thread safety but executed one at a time. ```haskell SeqForkUnlift :: UnliftStrategy ``` -------------------------------- ### Find Executable Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Searches for an executable file in the system's PATH environment variable. Returns Just the path if found, Nothing otherwise. Requires the FileSystem effect. ```haskell findExecutable :: (HasCallStack, FileSystem :> es) => String -> Eff es (Maybe FilePath) ``` -------------------------------- ### Copy File With Metadata Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Copies a file from a source path to a destination path, preserving metadata. Requires the FileSystem effect. ```haskell copyFileWithMetadata :: (HasCallStack, FileSystem :> es) => FilePath -> FilePath -> Eff es () ``` -------------------------------- ### List Directory Contents Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Lists the contents of a directory, returning a list of file and subdirectory names. Requires the FileSystem effect. ```haskell listDirectory :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es [FilePath] ``` -------------------------------- ### Import Pattern for Custom Effects (Static Dispatch) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Use this import for static dispatch when defining custom effects. ```haskell import Effectful.Dispatch.Static ``` -------------------------------- ### Running Concurrent Operations with Race Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/concurrent-effects.md Demonstrates using `race` to run two concurrent actions and retrieve the result of the one that finishes first. Requires `Effectful` and `Effectful.Concurrent.Async`. ```haskell import Effectful import Effectful.Concurrent.Async main :: IO () main = runEff $ runConcurrent $ do result <- race (liftIO $ threadDelay 1000000 >> pure "First") (liftIO $ threadDelay 500000 >> pure "Second") liftIO $ print result -- Right "Second" ``` -------------------------------- ### Handle File Not Found Exception Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Reads a file and handles a potential `DoesNotExistError` by returning a default string. Other `IOException`s are re-thrown. ```haskell import System.IO.Error (isDoesNotExistError) main :: IO () main = runEff $ do content <- catch (liftIO $ readFile "data.txt") (\e -> if isDoesNotExistError e then pure "File not found" else throwIO e) liftIO $ putStrLn content ``` -------------------------------- ### Running an Effectful Computation with IO Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/index.md Shows how to execute an Effectful computation that includes IO actions. The `runEff` function is used to enter the effectful context, and `liftIO` is used to perform IO operations. ```haskell import Effectful -- With IO main = runEff $ do liftIO $ putStrLn "Hello" ``` -------------------------------- ### Try Pattern with runErrorNoCallStack Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Illustrates the 'Try Pattern' using `runErrorNoCallStack` to handle potential errors by returning an Either type without including call stacks. ```haskell import Effectful import Effectful.Error.Static processData :: (Error String :> es) => String -> Eff es Int processData s = case reads s of [(n, "")] -> pure n _ -> throwError "Invalid number" main :: IO () main = runEff $ do result <- runErrorNoCallStack @String $ processData "42" liftIO $ print result -- Right 42 result2 <- runErrorNoCallStack @String $ processData "bad" liftIO $ print result2 -- Left "Invalid number" ``` -------------------------------- ### Import Pattern for Custom Effects (Dynamic Dispatch) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Use this import for dynamic dispatch when defining custom effects. ```haskell import Effectful.Dispatch.Dynamic ``` -------------------------------- ### High-level Unlift Strategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/advanced-effects.md Defines `withEffToIO` for converting effectful computations to IO, ensuring proper state handling. Requires the `IOE` effect to be present in the environment. ```Haskell withEffToIO :: IOE :> es => (forall a. Eff es a -> IO a) -> Eff es b -> Eff es b ``` -------------------------------- ### Copy File Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Copies a file from a source path to a destination path. Requires the FileSystem effect. ```haskell copyFile :: (HasCallStack, FileSystem :> es) => FilePath -> FilePath -> Eff es () ``` -------------------------------- ### Using Labeled Effects for Multiple Counters Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/advanced-effects.md Demonstrates how to use labeled effects to manage multiple independent stateful counters within a single effectful computation. Requires importing Effectful and Effectful.Labeled. ```haskell import Effectful import Effectful.Labeled import Effectful.State.Static.Local -- Multiple counters using labels multipleCounts :: ( Labeled "counter1" (State Int) :> es , Labeled "counter2" (State Int) :> es ) => Eff es (Int, Int) multipleCounts = do modify @"counter1" (+ 1) modify @"counter2" (+ 10) c1 <- get @"counter1" c2 <- get @"counter2" pure (c1, c2) main :: IO () main = runEff $ do ((c1, c2), (), ()) <- runState 0 . runState 0 -- First is counter2, second is counter1 . subsume $ sequentially (zoom @"counter1") (zoom @"counter2") multipleCounts liftIO $ putStrLn $ "Counter1: " ++ show c1 ++ ", Counter2: " ++ show c2 ``` -------------------------------- ### Find Executables In Directories Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Searches for an executable file within a specified list of directories. Requires the FileSystem effect. ```haskell findExecutablesInDirectories :: (HasCallStack, FileSystem :> es) => [FilePath] -> String -> Eff es [FilePath] ``` -------------------------------- ### Symbolic Links Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Functions for managing symbolic links within the file system. ```APIDOC ## Symbolic Links ### `createFileLink` #### Description Create a file symbolic link. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> FilePath -> Eff es ()` ### `createDirectoryLink` #### Description Create a directory symbolic link. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> FilePath -> Eff es ()` ### `removeDirectoryLink` #### Description Remove a symbolic link. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> Eff es () ### `pathIsSymbolicLink` #### Description Check if a path is a symbolic link. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> Eff es Bool` ### `getSymbolicLinkTarget` #### Description Get the target path of a symbolic link. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> Eff es FilePath ``` -------------------------------- ### Import Pattern for Advanced Features Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/module-structure.md Import this module for advanced features like labeled effects. ```haskell import Effectful.Labeled ``` -------------------------------- ### Define and Run a Custom Logger Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/index.md This snippet demonstrates how to define a custom effect 'Logger' with a 'Log' operation and implement its dynamic dispatch handler using 'interpret'. Use this for custom effect implementations. ```haskell import Effectful.Dispatch.Dynamic data Logger :: Effect where Log :: String -> Logger m () runLogger = interpret $ \_ -> \case Log msg -> liftIO $ putStrLn msg ``` -------------------------------- ### Bracket Pattern for Resource Management Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Shows the 'Bracket Pattern' for ensuring resource cleanup using `bracket`, even when errors occur within the usage block. ```haskell import Effectful.Exception main :: IO () main = runEff $ do bracket (liftIO $ putStrLn "Acquiring..." >> pure ()) (\_ -> liftIO $ putStrLn "Releasing...") (\_ -> do liftIO $ putStrLn "Using" error "Something went wrong") ``` -------------------------------- ### Find File In Directories Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Searches for a file within a specified list of directories. Returns Just the first path found, or Nothing. Requires the FileSystem effect. ```haskell findFile :: (HasCallStack, FileSystem :> es) => [FilePath] -> String -> Eff es (Maybe FilePath) ``` -------------------------------- ### Permissions Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Functions for managing file permissions. ```APIDOC ## Permissions ### `getPermissions` #### Description Get the permissions of a file. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> Eff es Permissions` ### `setPermissions` #### Description Set the permissions of a file. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> Permissions -> Eff es ()` ### `copyPermissions` #### Description Copy permissions from one file to another. #### Type `(HasCallStack, FileSystem :> es) => FilePath -> FilePath -> Eff es () ``` -------------------------------- ### Sequential Unlifting Function Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Provides a convenience function for unlifting with the sequential (SeqUnlift) strategy. It is equivalent to calling `withEffToIO SeqUnlift`. ```haskell withSeqEffToIO :: IOE :> es => ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a ``` ```haskell withSeqEffToIO = withEffToIO SeqUnlift ``` -------------------------------- ### Find Executables Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Finds all occurrences of an executable file in the system's PATH. Requires the FileSystem effect. ```haskell findExecutables :: (HasCallStack, FileSystem :> es) => String -> Eff es [FilePath] ``` -------------------------------- ### Check if File Exists Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Checks if a file exists at the given path. Requires the FileSystem effect. ```haskell doesFileExist :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es Bool ``` -------------------------------- ### Check if Path Exists Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Checks if a file or directory exists at the given path. Requires the FileSystem effect. ```haskell doesPathExist :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es Bool ``` -------------------------------- ### Cleanup and Finalization Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/exceptions-and-control.md Functions for resource cleanup and ensuring actions run. ```APIDOC ## Cleanup and Finalization ### Description Functions for resource cleanup and ensuring actions run. ### Functions - `bracket` - `Eff es a -> (a -> Eff es b) -> (a -> Eff es c) -> Eff es c` - Acquire, use, release pattern - `bracket_` - `Eff es a -> Eff es b -> Eff es c -> Eff es c` - Bracket without values - `bracketOnError` - `Eff es a -> (a -> Eff es b) -> (a -> Eff es c) -> Eff es c` - Bracket, cleanup only on error - `generalBracket` - `Eff es a -> (a -> ExitCase b -> Eff es c) -> (a -> Eff es b) -> Eff es b` - General bracket with exit case - `finally` - `Eff es a -> Eff es b -> Eff es a` - Ensure cleanup runs - `onException` - `Eff es a -> Eff es b -> Eff es a` - Run action only on exception - `withException` - `(Exception e) => Eff es a -> (e -> Eff es b) -> Eff es a` - Run handler on exception ``` -------------------------------- ### Set Current Working Directory Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Changes the current working directory to the specified path. Requires the FileSystem effect. ```haskell setCurrentDirectory :: (HasCallStack, FileSystem :> es) => FilePath -> Eff es () ``` -------------------------------- ### Handle System Errors with Exceptions Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Uses the `IOE` effect to catch `IOException`s during file reading. If an error occurs, it prints the error message and returns an empty string. ```haskell import Effectful.Exception readUserFile :: FilePath -> Eff es String readUserFile path = catch (liftIO $ readFile path) (\(e :: IOException) -> do liftIO $ putStrLn $ "File error: " ++ show e pure "") ``` -------------------------------- ### Handle Failure with Fail Effect (Maybe) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Demonstrates using the `Fail` effect, which is often used to emulate `Maybe`'s failure. `fail` is called to indicate an error, and `runFail` converts the `Eff` action into an `Either String a`. ```haskell import Effectful.Fail fallingAction :: Fail :> es => Eff es a fallingAction = fail "Something failed" main :: IO () main = runEff $ do result <- runFail fallingAction liftIO $ print result -- Left "Something failed" ``` -------------------------------- ### Multiple Handlers Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/exceptions-and-control.md Functions for catching multiple exceptions with a list of handlers. ```APIDOC ## Multiple Handlers ### Description Functions for catching multiple exceptions with a list of handlers. ### Functions - `catches` - `[Handler (Eff es) a] -> Eff es a -> Eff es a` - Catch with list of handlers - `catchesDeep` - `NFData a => [Handler (Eff es) a] -> Eff es a -> Eff es a` - Catches with deep eval ``` -------------------------------- ### Add Exception Context (GHC 4.20+) Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/errors.md Demonstrates adding context to an exception using `addExceptionContext`. The context is shown when the exception is caught and printed. ```haskell import Control.Exception (addExceptionContext) main :: IO () main = runEff $ do try $ catch (error "Original error" `addExceptionContext` "While processing user input") (\e -> liftIO $ putStrLn $ "Error with context: " ++ show e) ``` -------------------------------- ### Enable effectful-plugin Source: https://github.com/haskell-effectful/effectful/blob/master/effectful-plugin/README.md Add this GHC option to your project file to enable the effectful-plugin for improved effect disambiguation. ```text ghc-options: -fplugin=Effectful.Plugin ``` -------------------------------- ### Defining Multiple Labeled State Effects Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/advanced-effects.md Illustrates how to define an effect list with multiple distinct State effects, each identified by a unique type-level label. ```Haskell type MyEffects = [ Labeled "state1" (State Int) , Labeled "state2" (State String) ] ``` -------------------------------- ### Define XdgDirectory Type Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/types.md Enumerates standard XDG directories on Unix-like systems, such as data, config, cache, state, and runtime directories. Used for locating user-specific configuration and data files. ```haskell data XdgDirectory = XdgData | XdgConfig | XdgCache | XdgState | XdgRuntime ``` -------------------------------- ### Environment Effect Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/io-effects.md Functions for interacting with the system environment, including command-line arguments and environment variables. ```APIDOC ## Environment Effect ### `runEnvironment` #### Description Run computations with the Environment effect. #### Type `(HasCallStack, IOE :> es) => Eff (Environment : es) a -> Eff es a` ### `getArgs` #### Description Get the command-line arguments passed to the program. #### Type `(HasCallStack, Environment :> es) => Eff es [String]` ### `getProgName` #### Description Get the name of the program. #### Type `(HasCallStack, Environment :> es) => Eff es String` ### `getExecutablePath` #### Description Get the path to the executable. #### Type `(HasCallStack, Environment :> es) => Eff es FilePath` ### `getEnv` #### Description Get the value of an environment variable. #### Type `(HasCallStack, Environment :> es) => String -> Eff es String` ### `getEnvironment` #### Description Get all environment variables as a list of key-value pairs. #### Type `(HasCallStack, Environment :> es) => Eff es [(String, String)]` ### `lookupEnv` #### Description Look up an environment variable, returning `Maybe String`. #### Type `(HasCallStack, Environment :> es) => String -> Eff es (Maybe String)` ### `setEnv` #### Description Set an environment variable. #### Type `(HasCallStack, Environment :> es) => String -> String -> Eff es ()` ### `unsetEnv` #### Description Unset an environment variable. #### Type `(HasCallStack, Environment :> es) => String -> Eff es ()` ### `withArgs` #### Description Run a computation with modified command-line arguments. #### Type `(HasCallStack, Environment :> es) => [String] -> Eff es a -> Eff es a` ### `withProgName` #### Description Run a computation with a modified program name. #### Type `(HasCallStack, Environment :> es) => String -> Eff es a -> Eff es a ``` -------------------------------- ### Create Unlifting Function with Specific Strategy Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/configuration.md Provides a way to create an unlifting function (`Eff es r -> IO r`) using a specified `UnliftStrategy`. This is useful for integrating effectful computations into concurrent IO operations. ```haskell withEffToIO :: IOE :> es => UnliftStrategy -> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a ``` ```haskell import Effectful import Control.Concurrent.Async main :: IO () main = runEff $ do withEffToIO (ConcUnliftIO Persistent Unlimited) $ \unlift -> do liftIO $ do a1 <- async (unlift someEffectfulAction) a2 <- async (unlift anotherAction) r1 <- wait a1 r2 <- wait a2 print (r1, r2) ``` -------------------------------- ### Run a Pure Eff Computation Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/api-reference/eff-monad.md Use `runPureEff` to execute an Eff computation that has no side effects and returns a pure value. ```haskell import Effectful main :: IO () main = print $ runPureEff $ do pure (42 :: Int) ``` -------------------------------- ### Define XdgDirectoryList Type Source: https://github.com/haskell-effectful/effectful/blob/master/_autodocs/types.md Represents lists of XDG directories, specifically for data and configuration. This type is used when multiple locations for data or configuration files need to be considered. ```haskell data XdgDirectoryList = XdgDataDirs | XdgConfigDirs ```