In fact, this difference is just like the difference between a common function and a higher-order function. Isn't that easy to understand? Well, if you say you don't know what a high-order function is, don't read this article. Let's take a look at how I compared them.
Let's take a look at how EQ is defined in Haskell. I call it "normal typeclasses" (to distinguish the functor typeclasses, I call it P ), here we define a typeclasses and define an action in this typeclasses. The general saying is that you can think of this typeclasses as a Java interface, the behaviors of typeclasses are considered abstract methods in interfaces. A is a type variable, that is, any type can be used.
class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x == y = not (x /= y) x /= y = not (x == y)
Then we define a data type of our own.
data TrafficLight = Red | Yellow | Green
Since we think of typeclasses as an interface, it can be instantiated like an interface.
instance Eq TrafficLight where Red == Red = True Green == Green = True Yellow == Yellow = True _ == _ = False
During instantiation, we replace the type variable in typeclasses with the actual type trafficlight. Remember that this is the actual type, because this is the key to distinguishing functor typeclasses, in this way, a common typeclasses and an instance that implements EQ are defined.
Then we define a functor typeclasses to see how it is defined.
class Functor f where fmap :: (a -> b) -> f a -> f b
Define the data type. Let's talk about the following:
data Maybe a = Just a | Nothing
When defining the data type, A is added here. What is different from the trafficlig defined earlier?Maybe
Is a Type constructor that accepts a type as a parameter and returns a specific type. In my understanding, trafficlig directly defines the specific type for it, while maybe, after accepting a type variable A, is a specific type, in fact, it is an acceptable type. After accepting a type, it is also a specific type. For example, maybe is a Type constructor, after we replace type variable A with int, the entire maybe Int Is a specific type.
Let's take a look at the instantiation of factor typeclasses.
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
It is indeed different from the previous general typeclasses. During the instantiation, we passed in the Type constructor we mentioned earlier. Pretty, but what does the previous normal typeclasses accept? Yes, it is a specific type. We find the essential difference. Let's look at the differences between the Type constructor and the specific type again. The Type constructor accepts a type as a parameter and returns a specific type. Look at the function fmap (fmap
Accept a function, which maps from one type to another, also accepts a functor with the original type, and then returns a functor with the ing type ).
This associates him with the map high-level function. Let's take a look at the definition of map.
map :: (a -> b) -> [a] -> [b]
He accepts a function, which maps a type of things to another. Another string containing a certain type of list is converted into a list containing another type. Wow, it seems like fmap. Let's take a look at how list is defined as a functor instance.
instance Functor [] where fmap = map
Hahaha, perfect, is the map function. It is clear that functor is followed by a [] instead of [a]. Here [] is a Type constructor. After accepting a specific type, a specific type is returned, [a] is a specific type.
A common function, like a common typeclasses, accepts a specific type and returns a specific type.
For example:
fun :: Int -> Int
Accept an int type and return an int type.
After reading this, do you have a deeper understanding of functor typeclasses? P
Differences between functor typeclass and common typeclasses in Haskell