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.