Numbers in Haskell have lots of implicitness. Mentally, you ought to replace every number literal like 3
with fromInteger 3
. Since Amount
uses GeneralizedNewtypeDeriving
to be part of the Num
typeclass, it inherits a fromInteger
instance. So the compiler is doing this
usd 33 + 3
=== [implicit fromInteger & expand usd]
(Amount 33 :: Amount USD) +
fromInteger 3
=== [fromInteger :: Num a => a -> Amount a]
(Amount 33 :: Amount USD) +
(Amount 3 :: Amount a)
=== [unify a]
(Amount 33 :: Amount USD) +
(Amount 3 :: Amount USD)