The other methods have the following default definitions, which may be overridden with equivalent specialized implementations:
u *> v = pure (const id) <*> u <*> v
and
If f is also a Monad, it should satisfy
... (<*>) = ap
The (potential) trouble is that these have higher arities than is always natural. For example, it would seem reasonable to say
(<*>) Just f = fmap f
(<*>) Nothing = const Nothing
and to replace the default definition of (*>) like so:
(*>) a1 = (<*>) (id <$ a1)
but these are not strictly equivalent because they have arity 1 instead of arity 2. Would such definitions be be better in some cases? If so, should we weaken the rules a bit?