为什么没有`-XDeriveApplicative`扩展名? [英] Why is there no `-XDeriveApplicative` extension?

查看:107
本文介绍了为什么没有`-XDeriveApplicative`扩展名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆