Here are some definitions I wrote, to avoid mixing currencies
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
data EUR
data USD
newtype Amount a = Amount Double deriving (Fractional, Num, Show)
eur :: Double -> Amount EUR
eur = Amount
usd :: Double -> Amount USD
usd = Amount
usd 34 + usd 3type checks as expectedusd 33 + eur 33is a compilation error as expected- I'm surprised but
usd 33 + 3is OK according to the compiler. Something I wanted to avoid, and don't understand. I suspect it is becauseNuminstance, but then what is the difference with the second case?
Can you explain why usd 33 + 3 compiles and if it is possible to make the type-checker reject this expression.
Numbers in Haskell have lots of implicitness. Mentally, you ought to replace every number literal like
3withfromInteger 3. SinceAmountusesGeneralizedNewtypeDerivingto be part of theNumtypeclass, it inherits afromIntegerinstance. So the compiler is doing this