Opened 5 months ago

Closed 5 months ago

Last modified 5 months ago

#8506 closed bug (fixed)

misleading error message for duplicate type class instances

Reported by: carter Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 7.6.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: parser/should_fail/T8506 Blocked By:
Blocking: Related Tickets:

Description

In the following code I accidentally declared a type class more than once, and the error message had absolutely nothing to do with that!

{-# LANGUAGE PolyKinds   #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TemplateHaskell #-}

module Numerical.Types.Nat(Nat(..),nat)  where
import Data.Typeable
import Data.Data 
import Language.Haskell.TH hiding (reify)

data Nat = S !Nat  | Z 
    deriving (Eq,Show,Read,Typeable,Data)    

nat :: Int -> TypeQ
nat n
    | n >= 0 = localNat n
    | otherwise = error "nat: negative"
    where   localNat 0 =  conT 'Z
            localNat n = conT 'S `appT` localNat (n-1)



----------------------
----------------------

{-# LANGUAGE PolyKinds   #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Numerical.Types.Shape where


import Numerical.Types.Nat 
import Data.Data


type N0 = Z

type N1= S N0 

type N2 = S N1

type N3 = S N2 

type N4 = S N3

type N5 = S N4

type N6 = S N5

type N7 = S N6

type N8 = S N7  

type N9 = S N8

type N10 = S N9 


class Shapable (n :: Nat)   where 



-- zero rank is boring but lets include it for completeness
class Shapable Z where


class Shapable  One  where



{-
I get the following error

src/Numerical/Types/Shape.hs:97:17:
    Unexpected type `Z' where type variable expected
    In the declaration of `Shape Z'

-}


Change History (9)

comment:1 Changed 5 months ago by carter

GHC should give an error about multiple class instances, but I guess the renamer phase hits the constants in the instance heads before that multiple declaration conflict would happen.

Last edited 5 months ago by carter (previous) (diff)

comment:2 Changed 5 months ago by simonpj

You are both right. (Poor error message, but it comes from the parser.)

Is this better?

T8506.hs:54:16:
    Unexpected type ‛Z’
    In the class declaration for ‛Shapable’
    A class declaration should have form
      class Shapable a b c where ...

Simon

comment:3 Changed 5 months ago by carter

that'd be better. It brings attention to the whole "you wrote a class dec rather than an instance like you meant to"

Also, the paste above actually gives the following Error (assuming N1 is used rather than One ). Mixed up my examples when sharing

src/Numerical/Types/Shape.hs:88:16:
    Unexpected type `Z' where type variable expected
    In the declaration of `Shapable Z'

which is a bit inscrutable because it doesn't mention "you're declaring a class"

to clarify more, here's the snippet that triggered the original error (i gave a further reduced example above)

{-# LANGUAGE PolyKinds   #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TemplateHaskell #-}

module Numerical.Types.Nat(Nat(..),nat)  where
import Data.Typeable
import Data.Data 
import Language.Haskell.TH hiding (reify)

data Nat = S !Nat  | Z 
    deriving (Eq,Show,Read,Typeable,Data)    

nat :: Int -> TypeQ
nat n
    | n >= 0 = localNat n
    | otherwise = error "nat: negative"
    where   localNat 0 =  conT 'Z
            localNat n = conT 'S `appT` localNat (n-1)



----------------------
----------------------

{-# LANGUAGE PolyKinds   #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Numerical.Types.Shape where


import Numerical.Types.Nat 
import Data.Data


type N0 = Z

type N1= S N0 

type N2 = S N1

type N3 = S N2 

type N4 = S N3

type N5 = S N4

type N6 = S N5

type N7 = S N6

type N8 = S N7  

type N9 = S N8

type N10 = S N9 


class Shapable (n :: Nat)   where 
    data (Shape n ):: * 


-- zero rank is boring but lets include it for completeness
class Shapable Z where
    data Shape  Z = Shape0

class Shapable  (S Z)  where
    data Shape (S Z)  = Shape1  {-# UNPACK #-}  !Int 


{-
I get the following error

src/Numerical/Types/Shape.hs:97:17:
    Unexpected type `Z' where type variable expected
    In the declaration of `Shape Z'

-}

comment:4 Changed 5 months ago by simonpj

Yes, you included the snippet when you opened the ticket. I'll commit the improved message later today.

Simon

comment:5 Changed 5 months ago by Simon Peyton Jones <simonpj@…>

In 38438e1325461f8f6d32b21378cc10584e6b012e/ghc:

Improve a parser error message (Trac #8506)

comment:6 Changed 5 months ago by Simon Peyton Jones <simonpj@…>

comment:7 Changed 5 months ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to parser/should_fail/T8506

comment:8 Changed 5 months ago by carter

awesome, thanks!

I merely wanted to highlight the distinction of



src/Numerical/Types/Shape.hs:97:17:
    Unexpected type `Z' where type variable expected
    In the declaration of `Shape Z'

when theres a data family in the class

vs

src/Numerical/Types/Shape.hs:88:16:
    Unexpected type `Z' where type variable expected
    In the declaration of `Shapable Z'

because it wasn't clear to me, and that was part of why the original original snippet was especially confusing. Namely that it seemed to be saying I couldn't instantiate a data family (in addition to the whole typeclass dec needs to have variables as parameters)

comment:9 Changed 5 months ago by Simon Peyton Jones <simonpj@…>

In 384398b3eb2bc36a3e7b42a51495bd89398075b5/ghc:

Allow optional 'family' and 'instance' keywords in associated type instances

This is to allow

   class C a where
      type family F a
      type instance F a = Bool

   instance C Int where
      type instance F Int = Char

Plus minor improvements relating to Trac #8506
Note: See TracTickets for help on using tickets.