3

I'm encountering the following hard to understand behavior from GHC-8.2.2

I have some overlapping typeclass instances. No incoherent typeclass instances. There's a certain typeclass instance of the form, roughly,

instance (C f h, C g h) => D1 (D2 f g) h 

where C has overlapping instances. When I load my project into stack repl, all is well. The context of this instance is resolved to the instances of C I'm looking for.

If I create a file test.hs which imports a datatype falling under the instance above, all is not well. When I load that into stack repl, and call an operation of D1, then it's clear that the context of the instance of D1 is being resolved to the "wrong" instance of C.

What's especially strange is that if I add test.hs to my project as an exposed module, then reload it into the repl with no other changes, then the context of the instance above is resolved to the "right" instance of C.

I do not see this behavior with GHC-7.10.3, 8.0.1, 8.0.2, or with 8.4.3. Perhaps this is related to this bug?

But I'm not using incoherent instances, which is what that bug seems to involve. I am using a fair number of language extensions in the module where the instance above occurs:

{-#LANGUAGE TypeFamilies, UndecidableInstances, FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, GADTs,  DataKinds, PolyKinds, TypeOperators, PatternSynonyms, RankNTypes, FlexibleContexts, ScopedTypeVariables, DefaultSignatures #-}

I don't yet have a minimal example. A minimal example of the behavior can be found at GHC-Repro. Run test.sh to see the phenomenon. What I would like to know is:

  1. Whether this might conceivably be intended behavior by GHC, and I'm just doing something wrong.
  2. If I am doing something wrong, what I might do to select the "right" instance when importing stuff from my project into other projects.

This issue is now being tracked at: https://ghc.haskell.org/trac/ghc/ticket/15599

  • Can you please include code to reproduce the issue in your question? – jberryman Aug 16 '18 at 18:42
  • I haven't yet been able to boil it down to a snippet, but if you'd like to inspect it, you can clone the project at https://github.com/gleachkr/Carnap.git, checkout the branch "ghc-8-Odd-Inference", and compare the results of calling the function `test` from `Carnap/src/Carnap/Bad.hs` and `Carnap/src/Carnap/Good.hs` – Graham Leach-Krouse Aug 16 '18 at 21:07
  • Yeah this seems weird since all your instances are in the same file – jberryman Aug 16 '18 at 22:08
  • @jberryman: Added a link to a minimal example of the phenomenon. – Graham Leach-Krouse Aug 17 '18 at 21:02
  • Does the issue still occur if `Bad` is listed under extra modules and not expsoed modules? – sclv Oct 31 '18 at 05:09
  • @sclv sorry, It's possible I don't understand: do you mean other-modules? Also, it's `Good` that's listed and `Bad` that's unlisted. But (best attempt at an answer): switching `Good` from exposed-modules to other-modules preserves the weird behavior. FWIW, there was also some discussion at https://ghc.haskell.org/trac/ghc/ticket/15599. – Graham Leach-Krouse Nov 01 '18 at 17:14
  • You inferred my intent correctly. Thanks for the link! It's super weird, but reassuring that this only appears to occur in 8.2.2 and not other versions. It looks like the ticket you found actually notes this _can_ happen without incoherent instances, and was fixed in https://ghc.haskell.org/trac/ghc/ticket/14434 – sclv Nov 02 '18 at 04:20

0 Answers0