{-# LANGUAGE TypeApplications, OverloadedLabels, PolyKinds, DataKinds, ScopedTypeVariables, Rank2Types #-} import Data.Extensible import Prelude hiding (readFile) import Control.Exception import Data.ByteString (ByteString) data FileSystem r where ReadFile :: FilePath -> FileSystem (Either SomeException ByteString) readFile :: forall xs . (Associate "fs" FileSystem xs , Associate "fs_error" (EitherEff SomeException) xs) => FilePath -> Eff xs ByteString readFile fp = liftEff #fs (ReadFile fp) >>= either (throwEff #fs_error) pure foo :: forall xs. Associate "fs" FileSystem xs => Eff xs (Either SomeException ByteString) foo = castEff (runEitherEff @ "fs_error" (readFile "foo") :: Eff '["fs" >: FileSystem] (Either SomeException ByteString))