Firstly (2 :: Sum Integer)
.
Any literal integer in Haskell is rewritten by Haskell by wrapping it in a fromInteger
call. So:
(2 :: Sum Integer) == ((fromInteger (2 :: Integer)) :: Sum Integer)
Haskell just allows the notation on the left hand side so it's easier to type, but it's equivalent to the code on the right.
The fromInteger
function has the following type signature:
fromInteger :: Num a => Integer -> a
So (fromInteger (2 :: Integer))
has type Num a => a
Somewhere in the libraries you'll have an instance like the following:
instance Num a => Num (Sum a) where ...
As Integer
is a Num
, so is Sum Integer
.
So we can convert Num a => a
to Sum Integer
just by substituting a = Sum Integer
.
Finally, we have the Semigroup
function:
(<>) :: Semigroup a => a -> a -> a
There's also an instance:
instance Num a => Semigroup (Sum a) where ...
Somewhere in the semigroups modules, and as the (<>)
function specifies that the left and right argument and result has to be the same argument, then if we know one of these we know the other two. We know that the right argument is Sum Integer
, so we have to check we can convert the left argument to Sum Integer
.
Remember from before, 1
really means fromInteger (1 :: Integer)
. We've mention before that there's a fromInteger
implementation to Sum Integer
, so this is fine. We can then use the semigroup operation (<>)
on them as they're now the same type which is also a Semigroup
.
Answer for update
Num
is not a type, it's a class. Integer
is a type, but as I've said before, 43
is not an Integer
, it's fromInteger 43
. It can be an Integer
or it can be any Num
type. Some of those Num
types may be a Monoid
.
Try x = mappend (43 :: Integer)
and you'll find the code now fails to compile because you're forcing Num
to be an Int
which doesn't have a Monoid
instance.
However, x = mappend (43 :: Sum Integer)
does have a Monoid
instance so should compile fine.
(<>)
. – Code-ApprenticeNum
typeclass. The:: Sum Integer
on2
tells Haskell that2 :: Sum Integer
has typeSum Integer
(which has aNum
instance). Then, since(<>) :: Monoid m => m -> m -> m
, Haskell knows that1
must have the same type as2 :: Sum Integer
. – Alec2 :: Sum Integer
determine which type1
has to be? – softshipper<>
, which isMonoid a => a -> a -> a
. The types of both arguments must be identical. – user2407038