简体   繁体   English

Haskell:关于hackage Control.Applicative文章中应用函子法的描述中的缺陷?:它说Applicative确定了Functor

[英]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满足以下两个条件:

  1. t is an instance of Applicative fulfilling the rules above, and t是实现上述规则的Applicative的实例,并且
  2. There are two different implementations of 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是一个FunctorApplicative的实例,如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?


Edit 编辑

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语言扩展而改变感兴趣,例如我还不了解的FlexibleInstancesOverlappingInstances

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 = idfmap 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM