为什么 <*> 的 Const 实例接受两个非功能值?

Why does <*> of the Const instance accept two non-functional values?

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Const :: a -> Const a b
Monoid m => Applicative (Const * m)

Const "a" <*> Const "b" -- yields Const "ab"
Const a <*> Const a = Const a <> Const a

我想这种行为一定与 Const 是二进制类型构造函数这一事实有关,其中 b 从未被触及(幻像类型)。但是话又说回来,我不明白 Const * m,因为 a(和 * 分别)在这种情况下似乎被丢弃了。

首先如果m有一个Monoid实例,那么Const m有一个Applicative实例。但是 Const m 仍然是类型构造函数,所以 <*> 的类型 Applicative (Const m) 读取

     (<*>) :: Const m (a -> b) -> Const m a -> Const m b  

现在让我们将其应用于 Const "a"Const "b":

Const "a"Const String b 类型。所以上面的类型变量 m 假定类型 String。该值相对于 b 仍然是多态的,并且由于它不包含该类型的具体值,该类型仍然可以是任何类型。

在表达式 Const "a" <*> Const "b" 中,多态值 Const "a" 将被强制为 Const String (a->b) 类型,多态值 Const "b" 将被强制为 Const String a.

所以左边确实有一个带有函数类型的类型,只是具体值不包含函数,比如 Maybe (Int -> Int) 类型的值 Nothing

PS.: 我不知道Monoid m => Applicative (Const * m)中的*是从哪里来的。如果我输入

    :info Const

在 ghci 中,我得到了行

    instance Monoid m => Applicative (Const m)