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