#11397 closed bug (fixed)

Type mismatch in local definitions in Haskell 98 code

Reported by: Lemming Owned by: goldfire
Priority: highest Milestone: 8.0.1
Component: Compiler (Type checker) Version: 8.0.1-rc1
Keywords: TypeApplications Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: typecheck/should_compiler/T11397
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


Here is the affected code with all package dependencies removes:

$ cat PairMismatch.hs
module PairMismatch (inverseFrequencyModulationChunk) where

newtype VectorLazy a = VectorLazy a
newtype Vector a = Vector a
newtype Pointer a = Pointer a

empty :: VectorLazy a
empty = undefined

cons :: Vector a -> Pointer a
cons = undefined

unfoldrResult :: (a -> Either c (b, a)) -> a -> (VectorLazy b, c)
unfoldrResult = undefined

switchL :: b -> (a -> Pointer a -> b) -> Pointer a -> b
switchL = undefined

inverseFrequencyModulationChunk ::
   (Num t, Ord t) =>
   (s -> Maybe (t,s)) -> (t,s) -> Vector v -> (VectorLazy v, Maybe (t,s))
inverseFrequencyModulationChunk nextC (phase,cst0) chunk =
   let {-
       switch ::
          (Maybe (t, s) -> r) ->
          ((t, v) -> (s, Pointer v) -> r) ->
          t ->
          (s, Pointer v) -> r
       switch l r t (cp0,xp0) =
             (l Nothing)
             (\(c1,cp1) ->
                   (l (Just (t,cp0)))
                   (\x1 xp1 -> r (t+c1,x1) (cp1,xp1))
             (nextC cp0)

       go ::
          (t,v) -> (s, Pointer v) ->
          Either (Maybe (t,s)) (v, ((t,v), (s, Pointer v)))
       go (c,x) cxp =
          if c<1
            then switch Left go c cxp
            else Right (x, ((c-1,x),cxp))

   in  switch ((,) empty)
          (curry $ unfoldrResult (uncurry go))
          phase (cst0, cons chunk)

$  ghci- PairMismatch.hs 
GHCi, version http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling PairMismatch     ( PairMismatch.hs, interpreted )

PairMismatch.hs:35:24: error:
    • Couldn't match type ‘a’ with ‘(t, s)’
      ‘a’ is a rigid type variable bound by
        a type expected by the context:
          forall a. Maybe a
        at PairMismatch.hs:35:24
      Expected type: forall a. Maybe a
        Actual type: Maybe (t, s)
    • In the first argument of ‘l’, namely ‘(Just (t, cp0))’
      In the first argument of ‘switchL’, namely ‘(l (Just (t, cp0)))’
      In the expression:
          (l (Just (t, cp0))) (\ x1 xp1 -> r (t + c1, x1) (cp1, xp1)) xp0
    • Relevant bindings include
        cp1 :: s (bound at PairMismatch.hs:33:20)
        c1 :: t (bound at PairMismatch.hs:33:17)
        cp0 :: s (bound at PairMismatch.hs:30:22)
        t :: t (bound at PairMismatch.hs:30:19)
        r :: (t, t1) -> (s, Pointer t1) -> b
          (bound at PairMismatch.hs:30:17)
        switch :: ((forall a. Maybe a) -> b)
                  -> ((t, t1) -> (s, Pointer t1) -> b) -> t -> (s, Pointer t1) -> b
          (bound at PairMismatch.hs:30:8)
        inverseFrequencyModulationChunk :: (s -> Maybe (t, s))
                                           -> (t, s) -> Vector v -> (VectorLazy v, Maybe (t, s))
          (bound at PairMismatch.hs:22:1)
        (Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
Failed, modules loaded: none.

It works with GHC-7.10.3 and before. I may try to further simplify the code and choose a better ticket header, if I got an idea what went wrong.

Attachments (1)

PairMismatch.hs (1.4 KB) - added by Lemming 21 months ago.
Offending module as a separate file

Download all attachments as: .zip

Change History (8)

Changed 21 months ago by Lemming

Attachment: PairMismatch.hs added

Offending module as a separate file

comment:1 Changed 21 months ago by rwbarton

Milestone: 8.0.1
Priority: normalhighest

Setting as release blocker since it is a change in behavior in a supposedly Haskell 2010 program.

comment:2 Changed 21 months ago by monoidal

Smaller example:

module PairMismatch (f) where

f :: a -> [Maybe a]
f x =
   let switch l = [l Nothing, l (Just x)]
   in  switch id

While investigating this, I found two more programs that compile with GHC 7.10 but fail with HEAD, I'm not sure if the cause is the same or different.

module PairMismatch2 (f) where

u :: a
u = u

f :: a
f = let switch l = l u in switch u
module PairMismatch3 (f) where

f :: a
f = let switch l = l undefined in switch undefined

comment:3 Changed 21 months ago by simonpj

Keywords: TypeApplicaitons added
Owner: set to goldfire

Thanks for the examples. I think they are artefacts of TypeApplications, and the "return-tv" plumbing. Richard and I have a plan for this, which he is going to execute shortly

comment:4 Changed 21 months ago by simonpj

Keywords: TypeApplications added; TypeApplicaitons removed

comment:5 Changed 20 months ago by Richard Eisenberg <eir@…>

In 00cbbab3/ghc:

Refactor the typechecker to use ExpTypes.

The idea here is described in [wiki:Typechecker]. Briefly,
this refactor keeps solid track of "synthesis" mode vs
"checking" in GHC's bidirectional type-checking algorithm.
When in synthesis mode, the expected type is just an IORef
to write to.

In addition, this patch does a significant reworking of
RebindableSyntax, allowing much more freedom in the types
of the rebindable operators. For example, we can now have
`negate :: Int -> Bool` and
`(>>=) :: m a -> (forall x. a x -> m b) -> m b`. The magic
is in tcSyntaxOp.

This addresses tickets #11397, #11452, and #11458.


comment:6 Changed 20 months ago by goldfire

Status: newmerge
Test Case: typecheck/should_compiler/T11397

comment:7 Changed 20 months ago by bgamari

Resolution: fixed
Status: mergeclosed
Note: See TracTickets for help on using tickets.