为什么 <*> 的 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)
(<*>) :: 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)