First-order effect systems like freer-simple can make use of interpreters/effect interception to have pseudo higher-order actions, like handleError and catchError.
Unfortunately, such actions have semantic issues, since they rely on inspecting what effects are used of the target computation or rely on all uses of the relevant effect targeting a top-most effect of the effect stack -- either of which leads to incorrect results if intermediary effects get in the way.
Here's an example of freer-simple:
data SomeEff a where
SomeAction :: SomeEff String
someAction = send SomeAction
-- returns (Left "not caught")
bad :: Either String String
bad = run $ runError @String $ interpret (\SomeAction -> throwError "not caught") $
someAction `catchError` \(_ :: String) -> return "caught"
-- doesn't matter if "handleError" is used instead of "catchError"
Note that the exception doesn't get caught here even though both the use of throwError and catchError target the same Error effect. Compare this to polysemy, where the exception does, indeed, get caught.
I can't check this myself because I can't figure out custom compilers with cabal, but from what I've seen, eff uses the same approach as freer-simple for its higher-order effects -- the only difference between freer-simple's handleError and eff's catch is that the interpretation done on-site with handleError is done within the interpreter for catch. In this case, eff should have the same issue. Confirmed by @TheMatten.
First-order effect systems like
freer-simplecan make use of interpreters/effect interception to have pseudo higher-order actions, likehandleErrorandcatchError.Unfortunately, such actions have semantic issues, since they rely on inspecting what effects are used of the target computation or rely on all uses of the relevant effect targeting a top-most effect of the effect stack -- either of which leads to incorrect results if intermediary effects get in the way.
Here's an example of
freer-simple:Note that the exception doesn't get caught here even though both the use of
throwErrorandcatchErrortarget the sameErroreffect. Compare this topolysemy, where the exception does, indeed, get caught.I can't check this myself because I can't figure out custom compilers with cabal, but from what I've seen,Confirmed by @TheMatten.effuses the same approach asfreer-simplefor its higher-order effects -- the only difference betweenfreer-simple'shandleErrorandeff'scatchis that the interpretation done on-site withhandleErroris done within the interpreter forcatch. In this case,effshould have the same issue.