-
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.