Data.Data——为 arity 2 类型构造函数生成 dataCast1(部分专用)
因此 Data.Map 定义了 dataCast2,这是有道理的,因为它有一个 arity 2 类型构造函数。 dataCast1
默认为 const Nothing
。 dataCast2
很容易定义为 gcast2
。
供参考:
class Typeable a => Data a where
dataCast1 :: Typeable1 t => (forall d. Data d => c (t d)) -> Maybe (c a)
dataCast2 :: Typeable2 t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)
...
gcast1 :: (Typeable1 t, Typeable1 t') => c (t a) -> Maybe (c (t' a))
gcast2 :: (Typeable2 t, Typeable2 t') => c (t a b) -> Maybe (c (t' a b))
手头的问题是这样的:给定 Data.Data
、Data.Typeable
等中的所有内容,并给定一个 arity 2 类型构造函数,其中 dataCast2
已定义(例如, Map
或 (,)
),是否可以编写一个 dataCast1
版本对于这种类型构造函数的部分特化,无论是一次针对一个特定的构造函数,还是一般情况下,正确的做法是什么?
直觉上,我认为应该有一个很好的解决方案,但我的前几次尝试失败了。
So Data.Map has dataCast2
defined, which makes sense, as it has an arity 2 type constructor. dataCast1
defaults to const Nothing
. dataCast2
is easily defined as gcast2
.
For reference:
class Typeable a => Data a where
dataCast1 :: Typeable1 t => (forall d. Data d => c (t d)) -> Maybe (c a)
dataCast2 :: Typeable2 t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)
...
gcast1 :: (Typeable1 t, Typeable1 t') => c (t a) -> Maybe (c (t' a))
gcast2 :: (Typeable2 t, Typeable2 t') => c (t a b) -> Maybe (c (t' a b))
The question at hand is this: given everything in Data.Data
, Data.Typeable
, etc., and given an arity 2 type constructor for which dataCast2
is defined (say, Map
, or (,)
), is it possible to write a version of dataCast1
that does the right thing for a partial specialization of this type constructor, either for one specific constructor at a time, or in general?
Intuitively, I think there should be a good solution, but my first few tries crashed and burned.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定这是否是您想要的,但如果不是,它可能会引导您走向正确的方向。它的编写风格与 Data.Typeable 库中的
gcast
、gcast1
和gcast2
函数非常相似。有关更多详细信息,请“阅读来源,卢克”。使用此函数,您可以编写
foo
I'm not sure if this is what you want, but it might steer you in the right direction if it's not. It is written in a very similar style to the
gcast
,gcast1
, andgcast2
functions in the Data.Typeable library. For more details, "read the source, Luke".Using this function you can, for instance write
foo
根据这篇论文的方法Implement dataCast1 要么是 as
要么
他们没有说这是实现它的唯一方法,但情况可能是这样。也许值得问问作者?我认为核心问题是我们不能部分应用类型构造函数。例如,以下内容是不可能的
GHC 会抱怨 T 尚未应用于足够的类型参数。
不过我可以想到一个解决方法。我们定义了一个新类型,
这很烦人,但它可以完成工作。但也许它不符合您想要实现的目标。
According to this paper the way to implement dataCast1 is either as
or
They haven't said that this is the only way to implement it, but it might be the case. Perhaps it's worth asking the authors? I think the core problem is that we can't partially apply type constructors. e.g. the following is not possible
GHC will complain that T has not been applied to enough type arguments.
I can think of a work-around though. We define a newtype
It's pretty annoying but it does the job. But perhaps it doesn't fit with what you're trying to achieve.