Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9054877
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T13:47:48+00:00 2026-06-16T13:47:48+00:00

The GHC user’s guide describes the impredicative polymorphism extension with reference to the following

  • 0

The GHC user’s guide describes the impredicative polymorphism extension with reference to the following example:

f :: Maybe (forall a. [a] -> [a]) -> Maybe ([Int], [Char])
f (Just g) = Just (g [3], g "hello")
f Nothing  = Nothing

However, when I define this example in a file and try to call it, I get a type error:

ghci> f (Just reverse)

<interactive>:8:9:
    Couldn't match expected type `forall a. [a] -> [a]'
                with actual type `[a0] -> [a0]'
    In the first argument of `Just', namely `reverse'
    In the first argument of `f', namely `(Just reverse)'
    In the expression: f (Just reverse)
ghci> f (Just id)

<interactive>:9:9:
    Couldn't match expected type `forall a. [a] -> [a]'
                with actual type `a0 -> a0'
    In the first argument of `Just', namely `id'
    In the first argument of `f', namely `(Just id)'
    In the expression: f (Just id)

Seemingly only undefined, Nothing, or Just undefined satisfies the type-checker.

I have two questions, therefore:

  • Can the above function be called with Just f for any non-bottom f?
  • Can someone provide an example of a value only definable with impredicative polymorphism, and usable in a non-trivial way?

The latter is particularly with the HaskellWiki page on Impredicative Polymorphism in mind, which currently makes a decidedly unconvincing case for the existence of the extension.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T13:47:50+00:00Added an answer on June 16, 2026 at 1:47 pm

    Here’s an example of how one project, const-math-ghc-plugin, uses ImpredicativeTypes to specify a list of matching rules.

    The idea is that when we have an expression of the form App (PrimOp nameStr) (Lit litVal), we want to look up the appropriate rule based upon the primop name. A litVal will be either a MachFloat d or MachDouble d (d is a Rational). If we find a rule, we want to apply the function for that rule to d converted to the correct type.

    The function mkUnaryCollapseIEEE does this for unary functions.

    mkUnaryCollapseIEEE :: (forall a. RealFloat a => (a -> a))
                        -> Opts
                        -> CoreExpr
                        -> CoreM CoreExpr
    mkUnaryCollapseIEEE fnE opts expr@(App f1 (App f2 (Lit lit)))
        | isDHash f2, MachDouble d <- lit = e d mkDoubleLitDouble
        | isFHash f2, MachFloat d  <- lit = e d mkFloatLitFloat
        where
            e d = evalUnaryIEEE opts fnE f1 f2 d expr
    

    The first argument needs to have a Rank-2 type, because it will be instantiated at either Float or Double depending on the literal constructor. The list of rules looks like this:

    unarySubIEEE :: String -> (forall a. RealFloat a => a -> a) -> CMSub
    unarySubIEEE nm fn = CMSub nm (mkUnaryCollapseIEEE fn)
    
    subs =
        [ unarySubIEEE "GHC.Float.exp"    exp
        , unarySubIEEE "GHC.Float.log"    log
        , unarySubIEEE "GHC.Float.sqrt"   sqrt
        -- lines omitted
        , unarySubIEEE "GHC.Float.atanh"  atanh
        ]
    

    This is ok, if a bit too much boilerplate for my taste.

    However, there’s a similar function mkUnaryCollapsePrimIEEE. In this case, the rules are different for different GHC versions. If we want to support multiple GHCs, it gets a bit tricky. If we took the same approach, the subs definition would require a lot of CPP, which can be unmaintainable. Instead, we defined the rules in a separate file for each GHC version. However, mkUnaryCollapsePrimIEEE isn’t available in those modules due to circular import issues. We could probably re-structure the modules to make it work, but instead we defined the rulesets as:

    unaryPrimRules :: [(String, (forall a. RealFloat a => a -> a))]
    unaryPrimRules =
        [ ("GHC.Prim.expDouble#"    , exp)
        , ("GHC.Prim.logDouble#"    , log)
        -- lines omitted
        , ("GHC.Prim.expFloat#"     , exp)
        , ("GHC.Prim.logFloat#"     , log)
        ]
    

    By using ImpredicativeTypes, we can keep a list of Rank-2 functions, ready to use for the first argument to mkUnaryCollapsePrimIEEE. The alternatives would be much more CPP/boilerplate, changing the module structure (or circular imports), or a lot of code duplication. None of which I would like.

    I do seem to recall GHC HQ indicating that they would like to drop support for the extension, but perhaps they’ve reconsidered. It is quite useful at times.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following: parseExtensions :: GHC.Int.Int64 -> Get [Word32] parseExtensions size = do
Will GHC perform tail-call optimization on the following function by default? The only weird
When building gtk2hs-buildtools with ghc 7.4.2, I get the following warning: c2hs/toplevel/C2HSConfig.hs:110:1: Warning: newtype
I have the following line of code which when compiled with GHC it goes
I have just installed leksah following the user manual . The manual says that
I've just installed GHC 6.6 on OSX 10.6 and importing fails, for example module
Why is GHC's Int type not guaranteed to use exactly 32 bits of precision?
Is there a GHC language extension I can use to get polymorphic character literals?
In the GHC user manual GHCI debugger section, it is stated: GHCi has provided
When I compile the following code with GHC (using the -Wall flag): module Main

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.