Reading this Wikibook about Haskell and Category Theory basics, I learn about Functors:
A functor is essentially a transformation between categories, so given categories C and D, a functor F : C -> D
maps any object A in C to F(A), in D.
maps morphisms f : A -> B in C to F(f) : F(A) -> F(B) in D.
... which sounds all nice. Later an example is provided:
Let's have a sample instance, too:
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
Here's the key part: the type constructor Maybe takes any type T to a new type, Maybe T. Also, fmap restricted to Maybe types takes a function a -> b to a function Maybe a -> Maybe b. But that's it! We've defined two parts, something that takes objects in Hask to objects in another category (that of Maybe types and functions defined on Maybe types), and something that takes morphisms in Hask to morphisms in this category. So Maybe is a functor.
I understand how the definition of fmap
is key. I am confused about how the "type constructor Maybe" provides the first part. I would have rather expected something like pure
.
If I get it right, Maybe
rather maps C
to D
. (Thus being a morphism on category level, which might be a requirement for a Functor)
I guess you could rephrase my question like this: Is there a Functor that does not have an obvious implementation of pure
?
Functor
that does not admitpure
isdata Void a
. The instance looks likeinstance Functor Void where { fmap f x = case x of {} }
. (I'm not making this an answer because I don't think this example is particularly enlightening, even though it answers the only question you actually ask in the body.) – PampaFunctor
that doesn't admitpure
: if you have any valuev
in theFunctor
you can definepure x = x <$ v
. And I think every choice forpure
is of this form, too. Of course this is not usually very unique. – Bovillpure
. Here are a couple examples:instance Functor ((,) a)
hasfmap f (a, b) = (a, f b)
, but how would you implementpure
?pure x = (error "shit", x)
. If you managed to implementpure
you could obtainmagic = fst . pure ()
magic :: a
which is a sort of "proof" that such apure
would inherently involve_|_
. (I realizeMonoid a => (,) a
admits apure
, but(,) a
does not. Another example isinstance Functor (Map k)
, and yet another isinstance Functor (Const m)
. – Sarcoida
: I am making no claim about polymorphic type constructors. Ifa
has a value without bottoms then clearly you have apure
without bottoms too. And ifa
has no value, then it's isomorphic toVoid
. But I see now that laziness complicates matters, since(error "shit", x)
isn't itself bottom in Haskell. I think for these kinds of questions it is typical to ignore all bottoms (otherwise you could just saypure x = undefined
and be done with it), and then I think my claim is still true for any monomorphic example. – Bovillpure
is not inFunctor
, which it very much SHOULD NOT be. And even examples that are monomorphic don't necessarily have a "best" default. For example with listspure 5 :: ZipList Int
andpure 5 :: [Int]
are very very different, but both crucial for their respectiveApplicative
instances. – SarcoidMaybe
as their own category (a subcategory of Hask, to be sure)? If so the quote is perfectly correct. That's always how I've viewed Haskell Functors, rather than as endofunctors. They can be viewed as endofunctors of course, but because a type constructor always creates new types most endofunctors on Hask are not expressible as Haskell Functors. – Leonor