Consider this type:
newtype Ap f a = Ap (f a)
instance (Applicative f, Num a) => Num (Ap f a) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = pure . fromInteger
abs = fmap abs
signum = fmap signum
What needs to be true of f
for that instance to be lawful? Clearly, just being a lawful Applicative
isn't sufficient (e.g., x + negate x
is different than fromInteger 0
when x
is Ap Nothing
, even though Maybe
is a lawful Applicative
). My guess is that it's both necessary and sufficient for f
to be a representable functor. I'm not sure how to go about proving this, though (or finding a counterexample if it's false).
For the sake of reference, here are the laws suggested by the Num
documentation:
-- Associativity of (+)
(x + y) + z = x + (y + z)
-- Commutativity of (+)
x + y = y + x
-- fromInteger 0 is the additive identity
x + fromInteger 0 = x
-- negate gives the additive inverse
x + negate x = fromInteger 0
-- Associativity of (*)
(x * y) * z = x * (y * z)
-- fromInteger 1 is the multiplicative identity
x * fromInteger 1 = x
fromInteger 1 * x = x
-- Distributivity of (*) with respect to (+)
a * (b + c) = (a * b) + (a * c)
(b + c) * a = (b * a) + (c * a)