8
votes

I've had this question on the very back of my mind ever since I saw the definition of natural transformations in the Edward Kmett's old category-extras package:

-- | A natural transformation between functors f and g.
type f :~> g = forall a. f a -> g a

But now reading Stephen Diehl's blog post on adjunctions, I find this:

A natural transformation in our context will be a polymorphic function associated with two Haskell functor instances f and g with type signature (Functor f, Functor g) => forall a. f a -> g a. Which could be written with the following type synonym.

type Nat f g = forall a. f a -> g a

Which was a slap in the face of my "I'll continue ignoring this" attitude. So for the question: Why is okay to suddenly drop the functor constraints?

1
When you use Nat, you will be supplying types. The type synonym itself makes no use of the fact that they are Functors. Only when you use it does that make a difference, if that makes sense. - David Young
Hmmmm. The forall itself reduces the number of non-natural transform functions you can define, even if the Functors in question aren't initially evident/knocking about. - AndrewC
Read the excellent You could have defined natural transformations for a better explanation of the relationship between polymorphism and natural transformations. - AndrewC
I don't quite understand your first comment, even after reading the linked article. Sure, f and g have to be polymorphic - but that isn't the same as being a functor. What am I missing? And: thanks for the link; a quick read through it didn't settle my doubts, but it does seem very interesting. - user2141650
@user2141650 Actually, f and g don't need to be polymorphic (if you're talking about a specific natural transformation). For example, we might talk about the natural transformation safeHead :: Nat [] Maybe. a must be polymorphic and universally quantified though, for it to be natural. - David Young

1 Answers

2
votes

It is not allowed in Haskell to put a constraint on a type synonym. And even for datatypes, it has been deprecated in Haskell 2010. Instead, the constraint should be put on the functions that operate on values of this type.