【问题标题】:Generalised newtype deriving on class functions with Functors使用 Functor 派生类函数的广义新类型
【发布时间】: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 和函数coerceCoercible 表示在表示上相等的类型,即它们在运行时具有相同的表示形式,因此我们可以免费在它们之间进行转换。例如,给定:

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


【解决方案1】:

如果fFunctor,您可以为它制作一个“代表性包装”

data Rep f a where
    Rep :: (b -> a) -> f b -> Rep f a

它与f 同构,只是它在a 中具有代表性,这基本上是对f 可能具有的任何名义方差的存在量化。我认为这个结构恰好有一些花哨的范畴理论名称,但我不记得它是什么。要从Rep f a 中取出f a,您需要使用fFunctorhood。

您可以在您的方法中使用此包装器,确保您的类具有代表性。

alterFRep :: (Functor f) 
          => (Maybe (Value t) -> Rep f (Maybe (Value t))) -> Key t -> t -> Rep f t

然后通过使用与Rep f 的同构,使真正的“方法”只是一个常规函数。您还可以为实例作者创建一个方便的方法:

toAlterFRep :: 
    (forall f t. (Functor f) => (Maybe (Value t) -> f (Maybe (Value t))) -> Key t -> t -> f t)
 -> (forall f t. (Functor f) => (Maybe (Value t) -> Rep f (Maybe (Value t))) -> Key t -> t -> Rep f t)

所以他们不必担心Rep 到底是什么,他们只需正常实现alterF 并在其上使用toAlterFRep

【讨论】:

  • 那是Coyoneda f a。这是改变类型角色(对于函子)的一个非常令人印象深刻的技巧。我会认为这是不可能的。
猜你喜欢
  • 2013-09-11
  • 1970-01-01
  • 2016-03-27
  • 2020-02-28
  • 2016-09-17
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多