Hi everyone,
I’m reading the GHC Manual on RequiredTypeArguments
and it illustrates the implementation of the proposal with the following:
One advantage of required type arguments is that they are never ambiguous. Consider the type of
Foreign.Storable.sizeOf
:
sizeOf :: forall a. Storable a => a -> Int
The value parameter is not actually used, its only purpose is to drive type inference. At call sites, one might write
sizeOf (undefined :: Bool)
orsizeOf @Bool undefined
. Either way, theundefined
is entirely superfluous and exists only to avoid an ambiguous type variable.With
RequiredTypeArguments
, we can imagine a slightly different API:
sizeOf :: forall a -> Storable a => Int
If
sizeOf
had this type, we could writesizeOf Bool
without passing a dummy value.
Which sounds great. So I have tried to replicate it:
{-# LANGUAGE RequiredTypeArguments #-}
module Main where
import Data.Kind (Type)
class Storable (a :: Type) where
sizeOf :: forall a -> Int
instance Storable Int where
sizeOf _ = 8
Unfortunately I get all manners of type errors:
Main.hs:8:3: error: [GHC-39999]
• Could not deduce ‘Storable a0’
from the context: Storable a
bound by the type signature for:
sizeOf :: forall a {k}. Storable a => forall (a1 :: k) -> Int
at Main.hs:8:3-27
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘sizeOf’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method:
sizeOf :: forall a {k}. Storable a => forall (a1 :: k) -> Int
In the class declaration for ‘Storable’
|
8 | sizeOf :: forall a -> Int
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Am I missing something? Is there a complementary extension to enable?
Here is a playground link: https://play.haskell.org/saved/cotQbJ5Z