On page 321 of Real World Haskell
There are these codes,
...
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype AInt = A { unA::Int }
deriving (Show, Eq, Num)
instance Monoid AInt where
mempty = 0
My confusion is why it is
mempty = 0
but not
mempty = A 0
?
I also noticed that both
ghci> 0 :: AInt
and
ghci> A 0 :: AInt
give me the same response
A { unA = 0 }
Would someone please tell me what is the difference between theses two?
The trick here is with the GeneralizedNewtypeDeriving extension. In particular, this lets us derive any class for a newtype as long as the underlying type is an instance. All this does is copy over the instance from the old type to the new type.
In this particular case, AInt derives Num. This means that AInt is an instance of Num using the same code as Int (with everything wrapped in A constructors as appropriate). This includes Int's fromInteger function.
The fromInteger function is defined in terms of Int's fromInteger, looking something like this:
fromInteger i = A (fromInteger i)
Since 0 is polymorphic--it has the type 0 :: Num a => a--it's a valid constant for any type in Num. Thanks to the newtype deriving, this includes AInt, using the fromInteger function above. This means there is really no difference between 0 :: AInt an A 0 :: AInt.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With