http://learnyouahaskell.com/functors-applicative-functors-and-monoids :
Productis defined like this:newtype Product a = Product { getProduct :: a } deriving (Eq, Ord, Read, Show, Bounded)
Why is Product forced to be Bounded?
From the same book, a few paragraphs below:
Its instance for
Monoidgoes a little something like this:instance Num a => Monoid (Product a) where mempty = Product 1 Product x `mappend` Product y = Product (x * y)
Eh? The only constraint is Num a! But Num in particular means Integer, and this is not bounded (unlike Int), AFAIK.
Let's test it then:
import Data.Monoid
numbers :: [Integer]
numbers = [1..100]
main = print (getProduct . mconcat . map Product $ numbers)
Let's see this code in action:
m@m-X555LJ:~$ runhaskell wtf.hs
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
m@m-X555LJ:~$
Works. Doesn't fail.
So what's the bound of Product? Is there any bound of Product?
Let's play again:
m@m-X555LJ:~$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> minBound :: Int
-9223372036854775808
Prelude> maxBound :: Int
9223372036854775807
Prelude> import Data.Monoid
Prelude Data.Monoid> maxBound :: (Product Integer)
<interactive>:4:1: error:
• No instance for (Bounded Integer)
arising from a use of ‘maxBound’
• In the expression: maxBound :: Product Integer
In an equation for ‘it’: it = maxBound :: Product Integer
Prelude Data.Monoid> maxBound :: Product
<interactive>:5:13: error:
• Expecting one more argument to ‘Product’
Expected a type, but ‘Product’ has kind ‘* -> *’
• In an expression type signature: Product
In the expression: maxBound :: Product
In an equation for ‘it’: it = maxBound :: Product
Prelude Data.Monoid> maxBound :: (Product Int)
Product {getProduct = 9223372036854775807}
Prelude Data.Monoid>
Leaving GHCi.
m@m-X555LJ:~$
It doesn't seem that Product is, by itself, Bounded. Int is; but maxBound :: (Product Integer) throws! IIUC Product deriving Bounded is a promise that maxBound is well-defined on Product. Apparently, not always.
So why is Product an instance of Bounded?
Productis not an instance ofBounded(that would be a kind error, anyway). You're missing whatderivingactually does.There is a formal specification of derived instances in the Haskell report:
This means class constraints are automatically distributed to type parameters.
As explained in the section on
Bounded:For
Product, this meansProduct ais only an instance ofBoundedifais.