【发布时间】:2012-12-17 05:01:12
【问题描述】:
如果您可以执行以下操作(不一定使用这种格式,只是一般的想法),那就太好了:
data Sub = SubA | SubB
data Super = Sub | SuperB
isSub :: Super -> Bool
isSub Sub = True
isSub _ = False
所以 isSub SubA 会报告 True(而不是错误。) 目前您可能会执行以下操作:
data Super = SubA | SubB | SuperB
isSub :: Super -> Bool
isSub SubA = True
isSub SubB = True
isSub _ = False
它并不可怕或任何东西,但它不能很好地扩展(就像 Sub 到 SubZ 时这将非常笨重)并且它不允许您将 Sub 类型添加到它们自己的类型类中。为了避免这个问题,你可以包装 Sub:
data Sub = SubA | SubB
data Super = SuperA Sub | SuperB
isSub :: Super -> Bool
isSub (SuperA _) = True
isSub _ = False
但是现在您必须确保将您的 Subs 包装起来以将它们用作超级...再次不可怕;只是并没有真正表达出我想要的语义(即 Super 可以是任何 Sub 或 SuperB)。第一个(合法)示例是“Super 可以是 SubA...”,第二个是“Super 可以是采用 Sub...的 SuperA”
EDTI:更改一些名称以避免与音乐内容混为一谈。
附:从技术上讲,这开始于我考虑如何在 Haskell 中表示 Scheme 的数字塔......但我真的对表示“Type1 可以是 Type2 中的任何一个加上 x,y,......)的更一般的问题更感兴趣
【问题讨论】:
-
基于下面的答案和他们的 cmets:看起来,使用一些辅助函数导出最顶层的类型以从较低的类型创建该类型是解决此问题的最佳方法。
-
虽然看起来你需要为你的输入类型提供类型类(所以如果 SubA Int、SubB Float 和 SuperB String;那么你需要一个 Int 的 SubInput 类实例和 Float 以及 Int、Float 和 String 的 SuperInput 类实例。)至少,这些类可以是空的。但是你可以有 mkSub :: SubInput a => a -> Super
-
那么,您的问题是什么? :)
-
没有了。我得到了我想要的反馈......现在很难弄清楚2个答案中的哪一个更像是一个答案......
标签: haskell abstract-data-type