-
Notifications
You must be signed in to change notification settings - Fork 18
Description
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, Confirmed by @TheMatten.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.