Skip to content

Confusing error when checking that instance sig is more general

Summary

When using instance signatures in an attempt to avoid Proxy, GHC seemingly says that a signature is not more general than itself.

Steps to reproduce

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE InstanceSigs #-}

import Foreign.Storable

class Class where
  method :: forall t . Storable t => Int

instance Class where
  method :: forall t . Storable t => Int
  method = sizeOf (undefined :: t)

-- Note that this would work:
-- method :: forall t proxy . Storable t => proxy t -> Int

results in


Error.hs:12:13: error:
    • Could not deduce (Storable t0)
      from the context: Storable t
        bound by the type signature for:
                   method :: forall t. Storable t => Int
        at Error.hs:12:13-40
      The type variable ‘t0’ is ambiguous
    • When checking that instance signature for ‘method’
        is more general than its signature in the class
        Instance sig: forall t. Storable t => Int
           Class sig: forall t. Storable t => Int
      In the instance declaration for ‘Class’
   |
12 |   method :: forall t . Storable t => Int
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.

Expected behavior

I would hope for the error message to be more helpful. In this particular instance, perhaps t in one signature could be replaced by t0 or some other measure making it clearer why these two signatures aren't the same.

Environment

  • GHC version used: 8.8.1
Edited by Jakob Brünker
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information