Typeclass instance selection depends on the optimisation level
(See the attached files for a minimal case.)
A file A defines a typeclass, and gives an incoherent instance for all types a, and exports a function relying on said typeclass. A file B defines some data types, makes them specific instances of that class, and uses the function defined in A. Which instance ends up being picked for B depends on the optimisation level those files are compiled with.
//A.hs//
class A a where
someValue :: a -> Maybe Int
instance {-# INCOHERENT #-} A a where
someValue = const Nothing
getInt :: A a => a -> Int
getInt x = fromMaybe 0 $ someValue x
//B.hs//
data B = B Int
instance A B where
someValue (B x) = Just x
getBInt :: Int
getBInt = getInt $ B 42
//Main.hs//
main = print getBInt
- *Upon compiling with -O0, this prints 42; upon compiling with -O2, this prints 0.**
(Interestingly, if the redundant class constraint is removed from getInt, then it always prints 0.)