Skip to content

can't match type Bool with (), but shouldn't have to

The following (definitely type-incorrect) file:

{-# LANGUAGE ScopedTypeVariables #-}

runEffect :: Either Bool r -> r
runEffect = undefined

run :: forall a. a
run = runEffect $ (undefined :: Either a ())

produces the following error:

test.hs:7:7:
    Couldn't match type `Bool' with `()'
    Expected type: a
      Actual type: ()
    In the expression: runEffect $ (undefined :: Either a ())
    In an equation for `run':
        run = runEffect $ (undefined :: Either a ())

This is strange because one of the two types it claims it can't unify (Bool) doesn't appear in either the expected or actual type. Note that removing the ($) gets a different error message that makes it a bit more clear what's going on:

test.hs:7:18:
    Couldn't match type `Bool' with `()'
    Expected type: Either Bool a
      Actual type: Either a ()
    In the first argument of `runEffect', namely
      `(undefined :: Either a ())'
    In the expression: runEffect (undefined :: Either a ())
    In an equation for `run':
        run = runEffect (undefined :: Either a ())

So it seems it's trying to unify Bool and () because it's unifying both a with Bool and a with (); however, the usual comments about rigid type variables aren't there, which makes even this error message a bit confusing.

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