2

I was reading the Haskellbook and trying to test Monoid laws for a Monoid instance for a simple Bool like data type using the checkers library. But when I try to load the code in ghci, I get the following error:

BadMonoid.hs:21:20: error:
    • No instance for (QuickCheck-2.14:Test.QuickCheck.Arbitrary.Arbitrary
                         Bull)
        arising from a use of ‘monoid’
    • In the first argument of ‘quickBatch’, namely ‘(monoid Twoo)’
      In the expression: quickBatch (monoid Twoo)
      In an equation for ‘main’: main = quickBatch (monoid Twoo)
   |
21 | main = quickBatch (monoid Twoo)
   |                    ^^^^^^^^^^^
Failed, no modules loaded.

Though, I have defined an Arbitrary instance for my data type Bull. I have searched on the Internet and Stack Overflow and found a related post. I have tried the solution given there(using GHC.Generics) but it results in the same error. Here is the code:

module BadMonoid where
import Data.Monoid
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes

data Bull = Fools | Twoo deriving (Eq, Show)

instance Arbitrary Bull where
  arbitrary = frequency [(1, return Fools), (1, return Twoo)]

instance Monoid Bull where
  mempty = Fools

instance Semigroup Bull where
  (<>) _ _ = Fools

instance EqProp Bull where (=-=) = eq

main :: IO ()
main = quickBatch (monoid Twoo)
specdrake
  • 84
  • 1
  • 8
  • 4
    The inclusion of the QuickCheck version number in the error makes me suspicious; usually that means that one part of your dependency tree includes one version of QuickCheck and another part of your dependency tree includes a different version (e.g. perhaps `checkers` was built against version 2.14 and the `Arbitrary` instance in the file you show against a different version). The modern versions of the standard build tools make that failure mode much harder to hit, though; how are you building this code, and with which versions of the programs you invoke in that process? – Daniel Wagner Jun 05 '20 at 16:40
  • I had installed `checkers` using `cabal install checkers --lib`. I am using ghc 8.8.3. The code is not in a cabal or stack project. On trying to check the version of `checkers` using `cabal info checkers`. It shows `Not installed` while running `cabal install checkers --lib` shows `Up to date`. – specdrake Jun 05 '20 at 16:47
  • And you are building by calling `ghc` yourself, then? If so, I strongly recommend creating a simple cabal package (`cabal init` will guide you through the basic decisions and create a syntactically valid starter file for you), then use `cabal build` instead of `ghc`, `cabal repl` instead of `ghci`, etc. – Daniel Wagner Jun 05 '20 at 16:49
  • It worked in the cabal package. Thanks. But, I would like to know why it doesn't work outside it? Have I somehow installed two versions of QuickCheck? It's space consuming to make a package for every simple program. – specdrake Jun 05 '20 at 16:56

1 Answers1

3

The issue is that there are two incompatible versions of QuickCheck installed. We can tell from the error message, as it mentions the version (QuickCheck-2.14) in the type:

    • No instance for (QuickCheck-2.14:Test.QuickCheck.Arbitrary.Arbitrary
                         Bull)

As Daniel mentioned, the solution is to create a Cabal project that depends on QuickCheck and checkers, and use Cabal commands (e.g. cabal repl) instead of GHC directly.


By default, GHC can see every version of every package that's installed on the machine. But it doesn't know how to choose between them. If run on its own, it will pick whatever package versions it finds first – which may not consistent with each other.

Enter Cabal. The primary feature of Cabal is its solver: it can select a consistent set of packages, and tell GHC to only use those packages. That's why creating a Cabal project fixes the issue.

In general, it is an antipattern to run cabal install --lib. (Installing executables is okay, as they're self-contained.) If you need to install libraries from Hackage, create a Cabal project which depends on the library.

Lambda Fairy
  • 13,814
  • 7
  • 42
  • 68
  • Thanks a lot. I have a query though, I checked `~/.cabal/packages/hackage.haskell.org/QuickCheck/` and it contains only `2.14` folder. How can I view every version of a package installed systemwide? – specdrake Jun 06 '20 at 12:09
  • Try `ghc-pkg list QuickCheck`, or `ghc-pkg list` to see everything. – Lambda Fairy Jun 06 '20 at 12:17
  • Surprisingly neither of those commands shows that `QuickCheck` is installed. – specdrake Jun 06 '20 at 12:25
  • That's strange. Are there any [package environment](https://hexagoxel.de/postsforpublish/posts/2018-08-25-ghc-pkg-env-misfeature.html) files nearby? (I learned about those just now...) – Lambda Fairy Jun 07 '20 at 02:02
  • I couldn't find any package environment files in the directory. – specdrake Jun 07 '20 at 11:43