gks*_*ato 11 haskell functor hackage applicative
我想我在hackage文章中Control.Applicative
发现了一个缺陷.作为应用仿函数法的描述,它说:
Run Code Online (Sandbox Code Playgroud)class Functor f => Applicative f where
带有应用程序的仿函数,提供嵌入纯表达式(
pure
)和序列计算的操作,并组合它们的结果(<*>
).最小完整定义必须包括满足以下法则的这些函数的实现:
身分
Run Code Online (Sandbox Code Playgroud)pure id <*> v = v
组成
Run Code Online (Sandbox Code Playgroud)pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
同态
Run Code Online (Sandbox Code Playgroud)pure f <*> pure x = pure (f x)
互换
Run Code Online (Sandbox Code Playgroud)u <*> pure y = pure ($ y) <*> u
(请注意,这并未说明有关fmap的任何内容)并且它声明这些法律确定了Functor
实例:
作为这些法律的结果,
Functor
f 的实例将满足Run Code Online (Sandbox Code Playgroud)fmap f x = pure f <*> x
我一开始以为这显然是错的.也就是说,我猜测必须存在t
满足以下两个条件的类型构造函数:
t
是一个Applicative
履行上述规则的实例,并且instance (Functor t)
(即有两种不同的函数fmap1, fmap2 :: (a->b) -> (t a->t b)
,满足函子定律).如果(且仅当)上述内容正确,则必须重写上述语句
f的Functor实例必须满足
Run Code Online (Sandbox Code Playgroud)fmap f x = pure f <*> x
由于这些法律,这符合
Functor
法律.
这显然是正确的,无论我的猜测是否正确.
我的问题是:我猜是正确的吗?有没有t
所需的条件?
以下是我自己在试图回答这个问题时的想法.
如果我们仅仅是数学家对实际的Haskell编程不感兴趣,我们可以很容易地肯定地回答这个问题.事实上,
t = Identity
newtype Identity a = Identity {runIdentity :: a}
Run Code Online (Sandbox Code Playgroud)
符合上面的要求1和2(事实上,几乎任何事情都可以).实际上,它Identity
通常是一个实例,Functor
并且Applicative
正如其中所定义的那样Data.Functor.Identity
.(这满足fmap f = (pure f <*>)
.)instance (Functor f)
为每种类型定义另一个"实现" ,Take a
,两个函数
transf_a, tinv_a :: a -> a
Run Code Online (Sandbox Code Playgroud)
这样的
tinv_a . transf_a = id
Run Code Online (Sandbox Code Playgroud)
(从理论上讲,这很容易).现在定义
instance (Functor Identity) where
fmap (f :: a->b) = Identity . transf_b . f . tinv_a . runIdentity
Run Code Online (Sandbox Code Playgroud)
这符合Functor
法律,如果有的话,是与琐碎的法律不同的实现
x :: a
f :: a -> b
Run Code Online (Sandbox Code Playgroud)
这样的
f x /= transf_b $ f $ tinv_a x
Run Code Online (Sandbox Code Playgroud)
但是我们是否可以在Haskell中做到这一点并不明显.是这样的:
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
Run Code Online (Sandbox Code Playgroud)
可能在Haskell?
我忘了写一些非常重要的东西.我认识到Control.Applicative
作为GHC基础包的一部分,所以我也对我的问题的答案是否随任何GHC语言扩展而改变感兴趣,例如,FlexibleInstances
或者OverlappingInstances
我还不了解.
G P*_*lip 14
Haskell中的任何类型最多只能有一个实例Functor
,所以你的猜测是不正确的:因为没有类型t
可以存在两种不同的实现Applicative
.见:http://article.gmane.org/gmane.comp.lang.haskell.libraries/15384