【发布时间】:2018-02-18 19:13:17
【问题描述】:
我正在开发一个表示键/值映射的类,并且我有一个基本上类似于 alterF 的函数:
class C t where
...
alterF :: Functor f =>
(Maybe (Value t) -> f (Maybe (Value t))) -> Key t -> t -> f t
不幸的是,这打破了GeneralisedNewtypeDeriving。在某些情况下,这是合理的,因为据我了解,GeneralisedNewtypeDeriving 基本上使用了Coercible 和函数coerce。 Coercible 表示在表示上相等的类型,即它们在运行时具有相同的表示形式,因此我们可以免费在它们之间进行转换。例如,给定:
newtype T a = T a
我们有:
Coercible a (T a)
Coercible (T a) a
但我们没有(通常):
Coercible (f a) (f (T a))
Coercible (f (T a)) (f a)
例如,GADT 违反了这种表示平等。但是有很多 f 的值确实有效。例如:
Coercible (Maybe a) (Maybe (T a))
Coercible (Maybe (T a)) (Maybe a)
Coercible [a] [T a]
Coercible [T a] [a]
Coercible (Identity a) (Identity (T a))
Coercible (Identity (T a)) (Identity a)
我还想到这个实例可以写成:
Functor f => Coercible (f a) (f (T a))
Functor f => Coercible (f (T a)) (f a)
只使用fmap。与通常的coerce 不同,它在运行时不是免费的,但它会起作用。
所以我有一个包含 10 个函数的类,其中 9 个函数可以在 GeneralisedNewtypeDeriving 上正常工作。只有最后一个没有,可以使用fmap 机械解决。我是否必须为我的所有类函数编写自定义包装/展开实现,或者有没有办法要求我只为问题函数编写实现,或者诱使 GHC 使用 fmap 作为它的一部分 GeneralisedNewtypeDeriving ?
【问题讨论】:
-
你能分享你的开发成果链接吗?
标签: haskell