我的问题是:在声明实例以确保我声明实例的数据能够保证实现特定功能时,怎么可能?
这是一个例子
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'"等?
我知道这可能有点模糊,但我真的不知道如何描述我的问题。我以为我在上段很清楚。
答案 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