Skip to content

Why not use rank 2 polymorphism for callCC #127

@SmartHypercube

Description

@SmartHypercube

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    transformersBlocked on upstream transformers change

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions