简体   繁体   中英

Data constructor not in scope: Monoid :: Bull -> TestBatch

The Haskell book Haskell Programming From First Principles page 1086 has an example to demonstrate False should not be used as mempty of Monoid , but the code on this page does not compile, and I cannot figure out why. The code is here:

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
  mappend _ _ = Fools

main :: IO ()
main = do
  quickBatch (monoid Twoo)

The syntax checker shows two errors of this code:

• No instance for (Semigroup Bull)
    arising from the superclasses of an instance declaration
• In the instance declaration for ‘Monoid Bull’

and

• No instance for (EqProp Bull) arising from a use of ‘monoid’
• In the first argument of ‘quickBatch’, namely ‘(monoid Twoo)’
  In a stmt of a 'do' block: quickBatch (monoid Twoo)
  In the expression: do quickBatch (monoid Twoo)

loading this in stack ghci repl shows:

[1 of 1] Compiling BadMonoid        ( src/Main.hs, interpreted )

src/Main.hs:18:10: error:
    • No instance for (Semigroup Bull)
        arising from the superclasses of an instance declaration
    • In the instance declaration for ‘Monoid Bull’
   |
18 | instance Monoid Bull where
   |          ^^^^^^^^^^^

src/Main.hs:39:15: error:
    • No instance for (EqProp Bull) arising from a use of ‘monoid’
    • In the first argument of ‘quickBatch’, namely ‘(monoid Twoo)’
      In a stmt of a 'do' block: quickBatch (monoid Twoo)
      In the expression: do quickBatch (monoid Twoo)
   |
39 |   quickBatch (monoid Twoo)
   |               ^^^^^^^^^^^

Can you help me to fix this code? According to the book, the actual result should be:

Prelude> main
monoid:
  left  identity: *** Failed! Falsifiable (after 1 test):
Twoo
  right identity: *** Failed! Falsifiable (after 2 tests):
Twoo
  associativity:  +++ OK, passed 500 tests.

Thanks!

Looks like the definition of Monoid has changed since the book was written. As the documentation states :

NOTE : Semigroup is a superclass of Monoid since base-4.11.0.0 .

The instance should now look like this:

instance Monoid Bull where
  mempty = Fools

instance Semigroup Bull where
  _ <> _ = Fools

( mappend now simply calls <> .)

As for the EqProp instance, it can be derived from Eq as follows:

instance EqProp Bull where
  (=-=) = eq

Sorry for the second error:

I lost a line

instance EqProp Bull where (=-=) = eq

The first error:

I added

instance Semigroup Bull where _ <> _ = Fools

above the Monoid instantiation and the first error disappeared.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM