Opened 9 years ago

Closed 4 years ago

#1702 closed bug (fixed)

type operator precedences don't work in contexts

Reported by: b.hilken@… Owned by:
Priority: lowest Milestone: 7.6.2
Component: Compiler Version: 6.8
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by simonpj)

Type contexts don't parse correctly when a type class is used infix. The following example:

>    infixr 4 :=:
>    infixl 3 :+:
>    infix 2 `Disjoint`
>
>    labelZip :: (n :=: a `Disjoint` m :=: b) 
>             => n -> m -> [a] -> [b] -> [n :=: a :+: m :=: b]

gives the error:

    Type constructor `:=:' used as a class
    In the type `(:=: n (a Disjoint (m :=: b))) =>
                 n -> m -> [a] -> [b] -> [(n :=: a) :+: (m :=: b)]'
    In the type signature for `labelZip':
      labelZip :: (:=: n (a Disjoint (m :=: b))) =>
                  n -> m -> [a] -> [b] -> [(n :=: a) :+: (m :=: b)]

where the parenthesised version works.

Change History (16)

comment:1 Changed 9 years ago by simonpj

Description: modified (diff)

Absolutely right, good report.

It's really a structural flaw with historical origins. Infix expressions (including types) are sorted out by the renamer not the parser. This is a Good Thing. However, before the advent of infixity in types, the parser decides what the class is in the context of a type signature. But with infix stuff, the parser can't do that.

Solution: defer the unravelling of contexts until the renamer, removing it from the parser. I'll get to this but not until after ICFP.

Simon

comment:2 Changed 9 years ago by simonpj

Description: modified (diff)

comment:3 Changed 9 years ago by igloo

Milestone: 6.1

comment:4 Changed 9 years ago by simonpj

See also #1727

comment:5 Changed 9 years ago by simonmar

Architecture: powerpcMultiple
Operating System: MacOS XMultiple

comment:6 Changed 8 years ago by simonmar

Architecture: MultipleUnknown/Multiple

comment:7 Changed 8 years ago by simonmar

Operating System: MultipleUnknown/Multiple

comment:8 Changed 8 years ago by igloo

Milestone: 6.10 branch6.12 branch

comment:9 Changed 7 years ago by igloo

Milestone: 6.12 branch6.12.3

comment:10 Changed 7 years ago by igloo

Milestone: 6.12.36.14.1
Priority: normallow

comment:11 Changed 6 years ago by igloo

Milestone: 7.0.17.0.2

comment:12 Changed 6 years ago by igloo

Milestone: 7.0.27.2.1

comment:13 Changed 5 years ago by igloo

Milestone: 7.2.17.4.1

comment:14 Changed 5 years ago by igloo

Milestone: 7.4.17.6.1
Priority: lowlowest

comment:15 Changed 4 years ago by igloo

Milestone: 7.6.17.6.2

comment:16 Changed 4 years ago by monoidal

Resolution: fixed
Status: newclosed
Type of failure: None/Unknown

The code works fine in 7.6, with a minor change (type operators now do not use colons). It might have been fixed when constraint kinds were added. I opened #7609 to note a minor formatting error.

{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleContexts #-}
data (=:) a b
data (+:) a b
class Disjoint a b

infixr 4 =:
infixl 3 +:
infix 2 `Disjoint`

labelZip :: (n =: a `Disjoint` m =: b)
         => n -> m -> [a] -> [b] -> [n =: a +: m =: b]
labelZip = undefined
Note: See TracTickets for help on using tickets.