[Haskell-cafe] Best way to implement "scoped exceptions"?

Georgi Lyubenov godzbanebane at gmail.com
Tue May 27 20:07:55 UTC 2025


I think "scoped exceptions" is basically also the same thing as what 
https://github.com/tek/polysemy-resume#readme implements, so it might be 
of interest to you.

On 5/25/25 19:32, Tom Ellis wrote:
> On Wed, Dec 28, 2022 at 08:38:04PM +0000, Tom Ellis wrote:
>> I'd like to implement "scoped exceptions"[1], that is, a combinator of
>> type
>>
>>      withScopedException ::
>>          ((forall a. e -> IO a) -> IO r) ->
>> 	IO (Either e r)
> [...]
>> Here's a hacky way of doing it, based on tagging each exception with a
>> unique value, and then filtering when handling:
>>
>>    data MyException where
>>      MyException :: e -> Data.Unique.Unique -> MyException
>>    
>>    instance Show MyException where
>>      show _ = "<MyException>"
>>    
>>    instance Exception MyException
>>    
>>    withScopedException ::
>>      ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
>>    wiathScopedException f = do
>>      fresh <- Data.Unique.newUnique
>>      flip tryJust (f (\e -> throwIO (MyException e fresh))) $ \case
>>        MyException e tag ->
>>          -- unsafeCoerce is very unpleasant
>>          if tag == fresh then Just (unsafeCoerce e) else Nothing
>>        
>> This is the approach taken by the effectful library[2].  But is there
>> a better way?  Can I persuade GHC's RTS to work like this directly?
> I found a better way, or more accurately LSLeary suggested it to me,
> now implemented in Bluefin.Internal.Exception.Scoped:
>
> https://hackage-content.haskell.org/package/bluefin-internal-0.1.0.0/docs/Bluefin-Internal-Exception-Scoped.html
>
> The innovation is to have a `Key` type that supports:
>
>      newKey :: IO (Key a)
>      eqKey :: forall a b. Key a -> Key b -> Maybe (a :~~: b)
>
> This allows us to tag thrown values with a `Key` and unwrap them only
> when we have another copy of the same key, which allows us to obtain
> type equality.  (`Key` is also available in Apfelmus's `vault`
> package.)
>
> Tom
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.


More information about the Haskell-Cafe mailing list