Haskell数据类型列表

时间:2009-06-23 14:34:47

标签: haskell types

这可能是另一个简单的Haskell问题。如果我有一些“嵌套”数据类型,例如在此示例代码中:

data Place = Country
           | State
           | City String
           deriving Show

data State = California
           | NewYork
           deriving Show

data Country = USA
             | Canada
             deriving Show

我可以合法地制作[国家]类型的[美国,加拿大]或[州]类型的[加利福尼亚州,纽约州]或[地方类型的[城市“a”,城市“b”]等列表]

如何制作像[USA,NewYork]这样的清单,我该怎么办?纽约州是一个地方,美国是一个地方的国家,但是ghci看到美国所以它假定我正在制作一个国家名单(而纽约州是一个国家,因此名单失败)。

我认为我需要某种方式将国家或州置于一个地方,但我对如何实现这一目标感到茫然。

我正在努力避免将状态和国家/地区中包含的数据放入Place类型中,我知道这会使其工作,但是我有相当数量的实际数据,我宁愿不要混淆这一点。

3 个答案:

答案 0 :(得分:12)

这是一个更多的输出,使我找出问题:

*Main> [State, State]
[State,State]
*Main> :t State
State :: Place
*Main> :t NewYork
NewYork :: State

这似乎意味着“State”这个词是Place的有效构造函数,而数据State指的是只有California或NewYork的值。

如果稍微更改程序,请执行以下操作:

data Place = Country Country
           | State State
           | City String
           deriving Show

data State = California
           | NewYork
           deriving Show

data Country = USA
             | Canada
             deriving Show

然后你可以制作一个列表,例如[Country USA,State NewYork],它的类型是[Place]。使用与第一个示例中相同的单词两次不会以我认为的方式将State类型“绑定”在一起。

当然,使用构造函数State State只是一个偏好问题,如果我愿意,我可以轻松地在Place类型中AmericanState State

答案 1 :(得分:7)

{-# LANGUAGE ExistentialQuantification #-}
data GenericPlace = forall a. Show a => GenericPlace a
places :: [GenericPlace]
places = [GenericPlace USA, GenericPlace NewYork]

有关此方法的一些限制,请参阅GHC user guide # 7.4.4 Existentially quantified data constructors


对在Haskell中制作可用的异构集合进行了深入的研究。

  

Strongly typed heterogeneous collections

     

异构集合是一种数据类型,能够存储不同类型的数据,同时提供查找,更新,迭代等操作。存在各种异构集合,表示,不变量和访问操作不同。我们描述了HList ---一个用于强类型异构集合的Haskell库,包括可扩展记录。我们在Haskell中的类型安全数据库访问的上下文中说明了HList的好处。 HList库依赖于Haskell 98的常见扩展。我们的探索提出了有关Haskell类型系统的有趣问题,特别是避免重叠实例,以及类型相等和类型统一的具体化。

答案 2 :(得分:4)

您正在构建异构列表(即列表包含不同类型的值)。这种结构可以是静态或动态类型的。无论哪种方式,只要我们知道该值支持特定接口,我们就可以在包裹的列表中使用它。

最好的方法,IMO,是通过存在性打字,如ephemient显示:

  • 所有值都支持Show界面
  • 支持Show的任何内容都可以放在列表中
  • 类型系统保证你不能打破抽象