I think rank 2 polymorphism is a must-have for callCC, or this code will not compile:
f :: Int -> String
f x = (`runCont` id) $ callCC $ \exit -> do
y <- case x of
0 -> exit "error: x == 0"
_ -> pure x
yString <- case y of
1 -> exit "error: y == 1"
_ -> pure $ show y
pure yString
When calling functions like error, throwIO, or exit, which will never produce "normal" outputs, I generally expect the return type to be forall a. a in order to fit in any hole. But the exit produced by callCC does not work as expected. I wonder is there any specific reason?
I tried searching for related discussions, but all I could find is this article. It seems nobody is bothered by this? I have to use absurd to make it work in my code (absurd <$> exit "error: x == 0"). I'm curious about how others deal with this lack of polymorphism.
I'm definitely keen on making this happen, but this requires a major version bump. Once we land 2.3.1, I'm sure @emilypi wouldn't object to this change.
I think rank 2 polymorphism is a must-have for
callCC
, or this code will not compile:When calling functions like
error
,throwIO
, orexit
, which will never produce "normal" outputs, I generally expect the return type to beforall a. a
in order to fit in any hole. But theexit
produced bycallCC
does not work as expected. I wonder is there any specific reason?I tried searching for related discussions, but all I could find is this article. It seems nobody is bothered by this? I have to use
absurd
to make it work in my code (absurd <$> exit "error: x == 0"
). I'm curious about how others deal with this lack of polymorphism.