Skip to content

Confusing type error message

The following code (which is part of a bigger module) needs scoped type variables to compile.

run_state :: forall a s. State s a -> s -> (a,s)
run_state m s = observe_monad unit_op bind_op m where
  unit_op v          = (v,s)
  bind_op :: BindOp (StateE s) a (a,s)
  bind_op Get      k = run_state (k s) s
  bind_op (Put s1) k = run_state (k ()) s1

However, forgetting to turn on scoped type variables will give a very confusing error message:

Unimo.hs:56:36:
    Couldn't match expected type `s1' against inferred type `s'
      `s1' is a rigid type variable bound by
           the type signature for `bind_op' at Unimo.hs:55:28
      `s' is a rigid type variable bound by
          the type signature for `run_state' at Unimo.hs:52:22
    In the first argument of `k', namely `s'
    In the first argument of `run_state', namely `(k s)'
    In the expression: run_state (k s) s

Line 52 is the type signature of run_state and line 55 is the type signature of bind_op. The error message talks about a type variable `s1' which isn't mentioned anywhere. I guess the reason for this is that we have name collision and this is ghc's way of trying to tell the two variables apart. I don't think it works that well though. But I'm afraid I don't have any suggestion on how to make it better.

Trac metadata
Trac field Value
Version 6.8.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (Type checker)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system Unknown
Architecture Unknown
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information