【问题标题】:Removing repetitions from multiple instance declarations从多个实例声明中删除重复
【发布时间】:2017-03-23 05:24:00
【问题描述】:

我目前有遵循这种模式的代码:

f1' x1 x2 .. xm1 = ...
f2' x1 x2 .. xm2 = ...
.
.
,
fn' x1 x2 .. xmn = ...

instance C D1 where
  f1 = f1'
  f2 = f2'
  .
  .
  .
  fn = fn'

instance C D2 where
  f1 = f1'
  f2 = f2'
  .
  .
  .
  fn = fn'

.
.
.

instance C DN where
  f1 = f1'
  f2 = f2'
  .
  .
  .
  fn = fn'

基本上,我有一个要为多种数据类型实现的类,但所有这些实现都是相同的。但是实例实现有很多重复的代码,对于m函数和n实例,我必须大致写O(m*n)行代码,我希望它更像O(m+n)

有什么好的方法可以去掉这里的重复吗?我想 Template Haskell 可以解决问题,但如果已经存在处理这个问题的东西,我不想重新发明轮子。

【问题讨论】:

  • 如果都一样,就不能只提供默认实现吗?
  • 可悲的是,我不能这样做,我不控制班级(C 实际上是 Enum 在我的情况下)。
  • 代替抽象的例子,你能添加你的两个类型以及你的函数吗?
  • 我不知道有没有比 Template Haskell 更简单的东西。
  • 有时在这种情况下,我将每个实例的所有定义放在一行中,以减轻视觉上的痛苦并更清楚地显示重复。

标签: haskell


【解决方案1】:

您可以为您的类提供默认实现。以Functor 为例:

class  Functor f  where
    fmap        :: (a -> b) -> f a -> f b

     -- | Replace all locations in the input with the same value.
     -- The default definition is @'fmap' . 'const'@, but this may be
     -- overridden with a more efficient version.
    (<$)        :: a -> f b -> f a
    (<$)        =  fmap . const

你也可以选择deriving选项,你可以在这个问题中找到更多信息:How does deriving work in Haskell?有一些关于如何控制deriving的信息。

【讨论】:

  • C 不是我的课,只有实例是我的
  • 正在派生一个选项?
【解决方案2】:

也许你可以先创建另一个空类型类:

class SomeD

然后将类型 D1 ... DN 实例化为 SomeD 对每种类型使用单行:

instance SomeD D1
-- ...
instance SomeD DN

然后将SomeD 类型类的任何实例设为C 的实例,如下所示:

instance (SomeD t) => C t where
    f1 = f1'
    -- ...
    fn = fn'

(我不确定这是否可行,或者是否需要一些语言扩展,但不幸的是我现在无法对其进行测试。)

【讨论】:

  • 这不起作用,并且没有真正的扩展允许它。唯一可行的情况是没有C 的其他实现。是的,您可以编译它,但是当您尝试使用它时,一切都会变得混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2018-06-06
  • 2021-11-01
相关资源
最近更新 更多