回答
这是类似丹尼尔·普拉特的答案,但更典型的方法是放弃数据定义的类型约束,如下所示:
data SomeData a = SomeValue
| SomeConstructor a
相反,您应该将(Integral a)
约束放在任何需要它的函数上,即使您也将约束添加到数据定义中,您仍然必须执行该约束。对数据定义施加限制并不会带来任何收益,但会迫使您对SomeData
的所有用途施加约束,即使那些根本不在意a
的应用也是如此。有关更多信息,请参阅Chapter 10 of Real World Haskell。
例如,使用GADTs:
{-# LANGUAGE GADTs #-}
data SomeData
where
SomeValue :: SomeData
SomeConstructor :: Integral a => a -> SomeData
使用示例:
*Main> :t SomeValue
SomeValue :: SomeData
*Main> :t SomeConstructor 15
SomeConstructor 15 :: SomeData
*Main> :t SomeConstructor "aaa"
<interactive>:1:0:
No instance for (Integral [Char])
arising from a use of `SomeConstructor' at <interactive>:1:0-20
Possible fix: add an instance declaration for (Integral [Char])
In the expression: SomeConstructor "aaa"
*Main> let x = SomeConstructor 15 in case x of { SomeConstructor p -> fromIntegral p :: Int }
15
没有必要GADT那里,我猜。他们更有用'数据OtherData a其中{IntData :: Integral a => a - > OtherData a; EmptyData :: OtherData EmptyType'。即当你需要通过不同的构造函数产生一些特定的(有时派生的)类型的时候。 – ony 2010-07-06 06:52:24
你可以做这样的事情:
data Integral a => SomeData a =
SomeValue
| SomeConstructor a
当然,这取决于OP真正想要达到的目标。您的SomeData参数化类型为'a',而他的不是。此外,它看起来像他想对不同的构造函数应用不同的限制。 – 2010-07-05 20:46:57
如果SomeData不想被参数化,你可以将SomeValue拖出一个单独的类型,并通过它们加入它们,不是吗? – 2010-07-05 20:55:01
再一次,如果你这样做了,你可以通过'a'类型参数化。例如,您将无法拥有由不同积分制成的SomeData组成的列表。 未参数化的容器是“多态”容器 - 您可以放置任何东西(它遵守其限制),并且不会影响其类型。 – 2010-07-05 21:11:47
是的,完全按照你想要的,但需要一提的量化:
- 1. Haskell数据结构奇怪
- 2. Language.Haskell.Exts.Syntax.Module模板Haskell数据结构
- 3. 生成Haskell数据结构图
- 4. Haskell的数据结构SKOS(语义网)
- 5. Haskell和C之间交换结构化数据
- 6. 域结构的Haskell
- 7. 结构数据d = {0}和结构数据d = {}
- 8. 在haskell中可能“调用数据结构中的函数”吗?
- 9. 算法和数据结构
- 10. 编程和数据结构
- 11. 结构化,非结构化和半结构化数据
- 12. 树数据结构和数据
- 13. Haskell中的结构感应
- 14. Haskell可变堆结构
- 15. 有效交换元素的Haskell数据结构?
- 16. 使用预制数据结构在Haskell中进行备份
- 17. Haskell数据结构来模拟替代版本编号方法
- 18. 什么haskell数据结构来存储可变的树
- 19. Haskell - 用于稀疏矩阵乘以什么数据结构?
- 20. DB支持应用程序的Haskell数据结构
- 21. Haskell嵌套条件
- 22. 在haskell中构建图结构
- 23. 数据结构
- 24. 数据结构
- 25. 数据结构
- 26. 数据结构++
- 27. 数据结构
- 28. 数据库结构和查询层次数据和数据
- 29. 数据结构> queue:为什么(rear = front)是空的条件?
- 30. 如何将树数据结构保存到Haskell中的二进制文件
请注意,与普通数据声明的类约束不同,GADT *会提供类约束,因此您不必将其明确地放在函数上。 – 2010-07-05 22:12:49
GADT与限制数据定义类型的其他方式一样,通常不会以这种方式使用。一般来说,如果您只想限制这些值的类型,那么通常会更灵活,并且便于使用它的函数。 对于相反的情况,GADT更有用 - 当您需要*增加* 可以作为参数出现的类型,以及与此相关的模式匹配。 – Yitz 2010-07-06 08:11:15
@Antal S-Z:我猜你被数据SomeClass a => SomeData a where SomeData :: a - > SomeData a'和'data SomeData a where SomeData :: SomeClass a => a - > SomeData a'所迷惑。在第一种情况下,您还需要添加上下文'f :: SomeClass a => SomeData a',以便在多态类型'SomeData a'的声明中使用'a'。 – ony 2010-07-06 14:01:46