[英]Haskell: Flaw in the description of applicative functor laws in the hackage Control.Applicative article?: it says Applicative determines Functor
I think I found a flaw in the hackage article for Control.Applicative
. 我想我在
Control.Applicative
的hackage文章中发现了一个漏洞。 As a description of the applicative functor laws, it says: 作为应用仿函数法的描述,它说:
class Functor f => Applicative f where
A functor with application, providing operations to embed pure expressions (
pure
), and sequence computations and combine their results (<*>
).带应用程序的仿函数,提供嵌入纯表达式(
pure
)的操作,以及序列计算并组合它们的结果(<*>
)。A minimal complete definition must include implementations of these functions satisfying the following laws:
最小完整定义必须包括满足以下法则的这些函数的实现:
identity
身分
pure id <*> v = v
composition
组成
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
homomorphism
同态
pure f <*> pure x = pure (fx)
interchange
互换
u <*> pure y = pure ($ y) <*> u
(note that this does not say anything about fmap) and it states that these laws determine the Functor
instance: (请注意,这并没有说明fmap)并且它声明这些法则确定了
Functor
实例:
As a consequence of these laws, the
Functor
instance for f will satisfy作为这些定律的结果,f的
Functor
实例将满足fmap fx = pure f <*> x
I thought at first this was obviously wrong. 我一开始以为这显然是错的。 That is, I guessed there must exist a type constructor
t
satisfying the following two conditions: 也就是说,我猜一定存在一个类型构造
t
满足以下两个条件:
t
is an instance of Applicative
fulfilling the rules above, and t
是实现上述规则的Applicative
的实例,并且 instance (Functor t)
(ie there are two distinct functions fmap1, fmap2 :: (a->b) -> (t a->tb)
, satisfying the functor laws). instance (Functor t)
有两种不同的实现instance (Functor t)
(即有两个不同的函数fmap1, fmap2 :: (a->b) -> (t a->tb)
,满足函子定律)。 If (and only if) the above is correct, the above statement must be rewritten to 如果(且仅当)上述内容正确,则必须重写上述语句
The Functor instance for f must satisfy
f的Functor实例必须满足
fmap fx = pure f <*> x
As a consequence of these laws, this satisfies the
Functor
laws.由于这些法律,这符合
Functor
法律。
which is clearly correct, no matter whether my guess is right or not . 这显然是正确的, 无论我的猜测是否正确 。
My question is : is my guess correct? 我的问题是 : 我猜是正确的吗? Is there a
t
with the desired conditions? 是否有一个
t
与所需的条件是什么?
What follows is the explanation of what I thought during trying to answer this question by myself. 以下是我自己在试图回答这个问题时的想法。
If we were mere mathematicians uninterested in actual Haskell programming , we could easily answer this question affirmatively. 如果我们仅仅是数学家对实际的Haskell编程不感兴趣 ,我们可以很容易地肯定地回答这个问题。 In fact,
事实上,
t = Identity
newtype Identity a = Identity {runIdentity :: a}
meets the requirements 1 and 2 above (in fact, almost anything will do). 符合上面的要求1和2(事实上,几乎任何事情都可以)。 Indeed,
Identity
is trivially an instance of Functor
and Applicative
, as defined in Data.Functor.Identity
. 实际上,
Identity
是一个Functor
和Applicative
的实例,如Data.Functor.Identity
所定义。 (This satisfies fmap f = (pure f <*>)
.) To define another "implementation" of instance (Functor f)
, Take, for each type a
, two functions (这满足
fmap f = (pure f <*>)
。)为了定义instance (Functor f)
另一个“实现” instance (Functor f)
,对于每个类型a
,Take,两个函数
transf_a, tinv_a :: a -> a
such that 这样的
tinv_a . transf_a = id
(This is, set-theoretically , easy). (从理论上讲 ,这很容易)。 Now define
现在定义
instance (Functor Identity) where
fmap (f :: a->b) = Identity . transf_b . f . tinv_a . runIdentity
This satisfies the Functor
laws and is a different implementation from the trivial one if there are 这符合
Functor
法则,如果有的话,它是与琐碎的法则不同的实现
x :: a
f :: a -> b
such that 这样的
f x /= transf_b $ f $ tinv_a x
But it is not at all obvious whether we can do it in Haskell. 但是我们是否可以在Haskell中做到这一点并不明显。 Is something like:
是这样的:
class (Isom a) where
transf, tinv :: a -> a
instance (Isom a) where
transf = id
tinv = id
specialized instance (Isom Bool) where
transf = not
tinv = not
possible in Haskell? 可能在Haskell?
I forgot to write something very important. 我忘了写一些非常重要的东西。 I recognize
Control.Applicative
as part of GHC base package, so I am also interested in whether the answer to my question changes with any GHC language extensions, such as FlexibleInstances
or OverlappingInstances
, which I don't understand yet. 我认为
Control.Applicative
是GHC基础包的一部分,所以我也对我的问题的答案是否随任何GHC语言扩展而改变感兴趣,例如我还不了解的FlexibleInstances
或OverlappingInstances
。
Any type in Haskell can have at most one instance of Functor
, so your guess is not correct: For no type t
can there exist two different implementations of instance (Functor t)
. Haskell中的任何类型最多只能有一个
Functor
实例,所以你的猜测是不正确的:因为没有类型t
可以存在两个不同的instance (Functor t)
实现instance (Functor t)
。 See: http://article.gmane.org/gmane.comp.lang.haskell.libraries/15384 见: http : //article.gmane.org/gmane.comp.lang.haskell.libraries/15384
It is a property of the type a -> a
that there are only two inhabitants of it, namely id :: a -> a
(defined as id x = x
) and bottom :: a -> a
defined as bottom = error "Infinite loop."
它是a
a -> a
类型的属性,它只有两个居民,即id :: a -> a
(定义为id x = x
)和bottom :: a -> a
定义为bottom = error "Infinite loop."
. 。
If we restrict ourselves to only the first case as "reasonable", we come to an important mathematical theorem, which is that there is at most one function fmap
of type forall a. forall b. (a -> b) -> fa -> fb
如果我们仅将第一种情况局限于“合理”,我们得出一个重要的数学定理,即至少有一个类型为
forall a. forall b. (a -> b) -> fa -> fb
函数fmap
forall a. forall b. (a -> b) -> fa -> fb
forall a. forall b. (a -> b) -> fa -> fb
forall a. forall b. (a -> b) -> fa -> fb
satisfying fmap id = id
and fmap f . fmap g = fmap (f . g)
forall a. forall b. (a -> b) -> fa -> fb
满足fmap id = id
和fmap f . fmap g = fmap (f . g)
fmap f . fmap g = fmap (f . g)
. fmap f . fmap g = fmap (f . g)
。
If we do not, then you are correct, we have one case where fmap = undefined
and the other where fmap = (<*>) . pure
如果我们不这样做,那么你是正确的,我们有一个案例,其中
fmap = undefined
,另一个fmap = (<*>) . pure
fmap = (<*>) . pure
. fmap = (<*>) . pure
。 But that's a little cheesy. 但那有点俗气。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.