Tuple Constructors in Interface Instance Declarations Cause Illegal Instance Type Errors
Consider the following module:
module TupleConstructorInstance where
class C a where
methodC :: a Bool Bool
instance C (,) where
methodC = (True, False)
testExp :: (Bool, Bool)
testExp = methodC
Compiling this module works without problems, but using it interactively in PAKCS causes an Illegal instance type
error:
TupleConstructorInstance> testExp
Tests/.curry/pakcs-3.2.0/TupleConstructorInstance.icurry:8:12-8:14 Error:
Illegal instance type (,)
The instance type must be of the form (T u_1 ... u_n),
where T is not a type synonym and u_1, ..., u_n are
mutually distinct, non-anonymous type variables.
|
8 | instance C (,) {
| ^^^
ERROR occurred during parsing!
The cause of this error is the checkTypeConstructor
function in the interface syntax check (only the first part of it is displayed here):
checkTypeConstructor :: SpanInfo -> QualIdent -> ISC TypeExpr
checkTypeConstructor spi tc = do
tyEnv <- getTypeEnv
case qualLookupTypeKind tc tyEnv of
[] | not (isQualified tc) -> return $ VariableType spi $ unqualify tc
| otherwise -> do
report $ errUndefinedType tc
return $ ConstructorType spi tc
Unlike its counterpart checkType
in the type syntax check, checkTypeConstructor
does not have a special case for tuple constructors. You can see the isQTupleId tc
guard of the checkType
function here:
checkType :: TypeExpr -> TSCM TypeExpr
checkType c@(ConstructorType spi tc) = do
m <- getModuleIdent
tEnv <- getTypeEnv
case qualLookupTypeKind tc tEnv of
[]
| isQTupleId tc -> return c
| not (isQualified tc) -> return $ VariableType spi $ unqualify tc
| otherwise -> report (errUndefinedType tc) >> return c
This missing guard in checkTypeConstructor
means that the instance type (,)
is identified as a type variable in the interface syntax check. Type variables are not allowed as instance types however, therefore an Illegal instance type
error is reported.