| Actually both the Haskell and type script definitions don't communicate the concept of a functor well. Especially with the way it's used. The interface only requires you to implement the mapping between morphisms, but a mathematical functor also includes mappings between the objects from one category to the next. Additionally fmap is actually mapping (a -> b) to (f a -> f b)
but the way it's typically used in haskell breaks this intuition. Most people see it as ((a -> b), f a) to (f b)
as a result of how it's used in FP. Technically the usages are isomorphic but using it this way blocks your intuition from fully understanding the true nature of a functor.The following would be more a more accurate type class for a functor: class Functor f where
fmap :: (a -> b) -> (f a -> f b)
tmap :: a -> f a
See here:https://en.wikipedia.org/wiki/Functor Note that there are TWO axioms for functor, I added the second axiom to complete the definition. I think the reason why tmap doesn't exist is because it's trivial? Not sure maybe some expert can pitch in as I'm certainly not an expert in haskell. |
The typeclass you created would be a functor along with a natural transformation from the identity functor to f. I don't think these always exist, but they do for applicative functors (pure/return).
The object mapping is reflected at the type level. "f a" is the object that "f" sends "a" to.
In Haskell, functors are all endofunctors. In math, functors can be between categories, and in such a case a -> f a might not make any sense because there are no morphisms between categories.
Using some quasi-Agda syntax, here would be a full definition of a functor between two categories. Maybe you could overload "->" so that "X -> Y" could mean "Mor X Y" for the set of morphisms between X and Y in C or D (depending on context). Curly brackets mean optional parameters, which Haskell approximates via typeclasses.