GHC has four ways of creating instances:
stock: write new implementations of each of the class's methods from scratch via pattern matching and the like
newtype: when declaring a newtype that wraps a type that already has an instance, reuse that instance, inserting and removing newtype wrappers at the appropriate moments
anyclass: declare an instance with no method definitions (hence using default implementations for every method, if there are any)
via: a generalization of newtype, it lets you inherit the instance from any other type with visibly the same representation, again by inserting/removing newtype wrappers at appropriate moments
In your code snippet, the stock method is used to derive Functor because you have turned on DeriveFunctor. There is currently no stock derivation for Applicative, though. The via method only ever fires when explicitly requested, and you have not turned on DeriveAnyClass, so the only option left is newtype, so GHC attempts to inherit an instance from the wrapped type. Then it runs into trouble, because Applicative is supposed to be for container types, and the contained type isn't one, so it complains.
This explains the Functor vs Applicative difference for your first snippet. For the first vs second snippet difference for Applicative, we need only observe that after unwrapping the second one, we do have a container type; hence you get an Applicative instance for OK any time its f argument has one.
See also the documentation on deriving strategies.
:i Applicativeyou'll see this:type Applicative :: (* -> *) -> Constraint- so a type can be applicative if it's kind is* -> *(the container is applicative - like[]orMaybe- not[a],Maybe a) - that's why it is not working - your newtype is a wrapper for any type - if you'd make an instance forOKyou would doApplicative f => instance Applicative (OK f)(Ok f : * -> *) - try to write an instance forKOyourself - there is one (basicallyIdentity- look it up) - but it's not what you would expect from a newtype wrapper - Random DevIdentitybehaviour is what you want, you could useDerivingViaand saynewtype KO a = KO a deriving (Functor, Applicative) via Identity- kosmikusderiving viais more regular and less surprise - nicolas:i Functoralso showstype Functor :: (* -> *) -> Constraint. Why doesn'tFunctorpose the same problem, then? - EnlicoFunctordoesn't pose the same problem because it is using a different instance generation method. My answer has some details and a link to the full documentation. - Daniel Wagner