Why can you create a value with "Just (+)"?

Dan*_*mon 4 haskell type-parameter deriving

Currently I'm learning Haskell and are stuck with the instantiation of types to typeclasses. I actually don't understand, why it's possible to create a value of the Maybe a type with Just (+).

The problem why this behaves strange to me is, that the Maybe type is defined as an instance of the Eq typeclass (see Haskell source) and that if you derive an instance for a type, all the fields of the value / data constructors of that type must be also an instance of the Eq typeclass (here).

With this knowledge in mind, the following code shouldn't be compilable or executable, because a function is not a part of the Eq typeclass:

let a = Just (+)
let b = Just (-)
Run Code Online (Sandbox Code Playgroud)

But GHCi actually executes the code without throwing an error message. If you then try to compare these two values (which shouldn't also be possible) the interpreter comes up with the follwing error message:

a == b

<interactive>:24:1: error:
    * No instance for (Eq (Integer -> Integer -> Integer))
        arising from a use of `=='
        (maybe you haven't applied a function to enough arguments?)
    * In the expression: a == b
      In an equation for `it': it = a == b
Run Code Online (Sandbox Code Playgroud)

This problem also occurs if you create your own Maybe a type.

luq*_*qui 12

The instance of Eq for Maybe ends up looking like this (that is, deriving (Eq) essentially gets rewritten into this):

instance (Eq a) => Eq (Maybe a) where
    ...
Run Code Online (Sandbox Code Playgroud)

This can be read as if a is a member of Eq, then so is Maybe a. So it's perfectly fine to make a Maybe (Int -> Int) or what have you, it just won't be Eq if its argument isn't.

A more operationally helpful way to think of this, more from the compiler's point of view: to solve a Eq (Maybe a) constraint, it suffices to solve the Eq a constraint. So when we say

a == b
Run Code Online (Sandbox Code Playgroud)

编译器尝试解决Eq (Maybe (Integer -> Integer -> Integer))。它使用Maybe实例将问题简化为Eq (Integer -> Integer -> Integer),然后在它无能为力时放弃。这就是为什么您看到错误消息抱怨没有实例Eq (Integer -> Integer -> Integer)而不是提及的原因Maybe