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实例:
作为这些法律的结果,
Functorf 的实例将满足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