为什么没有`-XDeriveApplicative`扩展名? [英] Why is there no `-XDeriveApplicative` extension?
问题描述
GHC有几种有用的语言扩展,用于机械地获取各种常见Haskell类型类( -XDeriveFunctor
, -XDeriveFoldable
, -XDeriveTraversable
)。看起来, Applicative
是另一个经常需要且经常容易派生的类。对于包含 a
类型的插槽的简单记录,例如,
data SimpleRecord a =简单aaa
Applicative 实例被简单地派生出来,
实例Applicative SimpleRecord其中
pure x =简单xxx
简单a1 b1 c1 *< *>简单的a2 b2 c2 =简单的(a1 a2)(b1 b2)(c1 c2)
即使在稍微难一些的案例,其中一些 a
值被掩埋在其他应用函子中,例如,
data MyRecord fa = MyRecord(fa)a
合理实例很容易写出,
instance(Applicative f)=> Applicative(MyRecord f)其中
pure x = MyRecord(纯x)x
MyRecord a1 b1 * MyRecord a2 b2 = MyRecord(a1 * a2)(b1 b1)
为什么是否存在实现这些机械实例的 -XDeriveApplicative
扩展?即使派生
和泛型派生
包明显缺少 Applicative 支持。是否有理论上的问题阻止这些实例通常是有效的(除了那些可能威胁
Functor
, Foldable
,或 Traversable
扩展)?
的 Functor
,以符合仿函数法则的给定数据类型。例如, map
是 fmap
列表的唯一合法实现:
fmap id == id
fmap(f。g)== fmap f。 fmap g
但是可以有多个守法的实例
纯id< *>< / code> v == v
pure(。)*< u * v * w == u * * (v * w)
纯f *纯x ==纯(f x)
u *纯y =纯($ y)* u
对于清单,<>
可以表现得像 \fs xs - > concatMap(\f-> map f xs)fs
或者像 zipWith($)
,并且不清楚哪一个编译器应该选择。
GHC has several useful language extensions for mechanically deriving various common Haskell typeclasses (-XDeriveFunctor
, -XDeriveFoldable
, -XDeriveTraversable
). It seems that Applicative
is another class which is often needed and frequently easily derived. For a simple record containing slots of type a
, e.g.,
data SimpleRecord a = Simple a a a
the Applicative
instance is trivially derived,
instance Applicative SimpleRecord where
pure x = Simple x x x
Simple a1 b1 c1 <*> Simple a2 b2 c2 = Simple (a1 a2) (b1 b2) (c1 c2)
Even in the slightly harder case where some a
values are buried in other applicative functors, e.g.,
data MyRecord f a = MyRecord (f a) a
a reasonable instance is easily written,
instance (Applicative f) => Applicative (MyRecord f) where
pure x = MyRecord (pure x) x
MyRecord a1 b1 <*> MyRecord a2 b2 = MyRecord (a1 <*> a2) (b1 b1)
Why is it that a -XDeriveApplicative
extension implementing these sorts of mechanical instances does not exist? Even the derive
and generic-derive
packages apparently lack Applicative
support. Is there a theoretical issue precluding these instances from being usually valid (beyond those reasons that might also threaten the Functor
, Foldable
, or Traversable
extensions)?
There is at most one instance of Functor
for a given data type that follows the functor laws. For example, map
is the only lawful implementation of fmap
for lists:
fmap id == id
fmap (f . g) == fmap f . fmap g
But there can be more than one law-abiding instance of Applicative
, which isn’t necessarily obvious.
pure id <*> v == v
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
pure f <*> pure x == pure (f x)
u <*> pure y == pure ($ y) <*> u
For lists, <*>
can behave like \fs xs -> concatMap (\f -> map f xs) fs
or like zipWith ($)
, and it isn’t clear which one the compiler should choose.
这篇关于为什么没有`-XDeriveApplicative`扩展名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!