gpt4 book ai didi

haskell - 为什么没有 `-XDeriveApplicative`扩展名?

转载 作者:行者123 更新时间:2023-12-02 08:14:49 28 4
gpt4 key购买 nike

GHC 有几种有用的语言 extensions用于机械派生各种常见的 Haskell 类型类(-XDeriveFunctor-XDeriveFoldable-XDeriveTraversable)。看起来 Applicative 是另一个经常需要并且经常很容易派生的类。对于包含 a 类型槽的简单记录,例如,

data SimpleRecord a = Simple a a a

Applicative 实例是简单派生的,

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)

即使在稍微困难的情况下,一些 a 值被隐藏在其他应用仿函数中,例如,

data MyRecord f a = MyRecord (f a) a

合理的实例很容易编写,

instance (Applicative f) => Applicative (MyRecord f) where
pure x = MyRecord (pure x) x
MyRecord a1 b1 <*> MyRecord a2 b2 = MyRecord (a1 <*> a2) (b1 b1)

为什么实现此类机械实例的 -XDeriveApplicative 扩展不存在?即使是 derive 和 generic-derive 包也显然缺乏 Applicative 支持。是否存在阻止这些实例通常有效的理论问题(除了那些可能威胁 Functor、Foldable 或 Traversable 扩展的原因之外) ?

最佳答案

最多有一个 Functor 的实例对于遵循仿函数定律的给定数据类型。例如,mapfmap 的唯一合法实现对于列表:

fmap id      == id
fmap (f . g) == fmap f . fmap g

但是 Applicative 的守法实例可能不止一个,这不一定是显而易见的。

pure id <*> v              == v
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
pure f <*> pure x == pure (f x)
u <*> pure y == pure ($ y) <*> u

对于列表,<*>可以表现得像 \fs xs -> concatMap (\f -> map f xs) fs或类似zipWith ($) ,并且不清楚编译器应该选择哪一个。

关于haskell - 为什么没有 `-XDeriveApplicative`扩展名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18861231/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com