language pragma order matters
Summary
Speculating a little bit: when one extension implies another, that overrides previous explicit requests about whether the implied extension should be on or not. I think explicit user request should take precedence over the implicit requests by implication. (And, generally, I think the order that language pragmas are declared in should not matter.)
Steps to reproduce
The following code compiles fine:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoMonoLocalBinds #-}
data Data = Data { foo :: Int, bar :: Double }
baz :: Data -> Data -> Bool
baz d1 d2 = check foo && check bar where
check f = f d1 == f d2
However, switching the order of the pragmas causes it to stop compiling:
{-# LANGUAGE NoMonoLocalBinds #-}
{-# LANGUAGE TypeFamilies #-}
data Data = Data { foo :: Int, bar :: Double }
baz :: Data -> Data -> Bool
baz d1 d2 = check foo && check bar where
check f = f d1 == f d2
For completeness, I'll include the error, though I think the cause is probably pretty clear:
test.hs:7:32: error:
• Couldn't match type ‘Double’ with ‘Int’
Expected type: Data -> Int
Actual type: Data -> Double
• In the first argument of ‘check’, namely ‘bar’
In the second argument of ‘(&&)’, namely ‘check bar’
In the expression: check foo && check bar
|
7 | baz d1 d2 = check foo && check bar where
| ^^^
Expected behavior
I expect both code snippets to compile without error.
Environment
- GHC version used: 8.8.1
- Operating System: Fedora 30, Linux 5.3.7
- System Architecture: x86-64