保证具有某种功能的实例

时间:2018-04-28 10:57:42

标签: haskell

我的问题是:在声明实例以确保我声明实例的数据能够保证实现特定功能时,怎么可能?

这是一个例子

   class AClass x where
     create :: String -> x

   data D1 = D1 { d1 :: String }

   data D2 = D2 { d2 :: String }

   instance AClass D1 where
     create s = if s == [] then D1 "D1Default" else D1 s

   instance AClass D2 where
     create s = if s == [] then D2 "D2Default" else D2 s

现在让我们在一个实际例子中说这个函数比这里复杂,但除了默认和自定义构造函数之外的所有实例都相同。

所以我想写的是这样的:

    class AClass x where
      create :: String -> x

    data D1 = D1 { d1 :: String }

    data D2 = D2 { d2 :: String }

    class MyClass x where
      myDefault :: x
      myCustom :: String -> x

    instance (MyClass x) => AClass MyClass where
      create s = if s == [] then myDefault else myCustom s

现在我意识到这段代码有很多问题。它应该只展示我想要做的事情。

我也发现了这个问题(How do I write, "if typeclass a, then a is also an instance of b by this definition."),我觉得它可以为我的问题提供解决方案,但我无法将其解决方案与我正在寻找的问题完全匹配。

----编辑----

因为这个问题似乎令人困惑,所以我会尝试区别对待:

假设您有一个使用类 C 的库。您想为此类创建多个实例 I1 ,..., In 。这些实例都有一个函数 f ,除了一个字符串外,每个 Ii 的实现几乎相同。为每个 f 执行约20行代码会导致大量代码重复,这是您要避免的。因此问题变成:如何以通用方式创建单个实例,以便稍后只需说" I1 使用字符串' Foo',&#34 ; I2 使用字符串' Bar'"等?

我知道这可能有点模糊,但我真的不知道如何描述我的问题。我以为我在上段很清楚。

1 个答案:

答案 0 :(得分:3)

我认为在这里引入一个额外的课程是不明智的。为什么不使用简单的高阶辅助函数:

createUsingDefault :: x -> (String -> x) -> String -> x
createUsingDefault def _ "" = def
createUsingDefault _ constr s = constr s

instance AClass D1 where
 create = createUsingDefault (D1 "D1Default") D1
instance AClass D2 where
 create = createUsingDefault (D2 "D2Default") D2

甚至

createUsingDefault :: String -> (String -> x) -> String -> x
createUsingDefault def constr "" = constr $ def++"Default"
createUsingDefault _ constr s = constr s

instance AClass D1 where
 create = createUsingDefault "D1" D1
instance AClass D2 where
 create = createUsingDefault "D2" D2