简体   繁体   English

Haskell数据类型列表

[英]Haskell lists of datatypes

This is probably another easy Haskell question. 这可能是另一个简单的Haskell问题。 If I have some "nested" data types, such as in this example code: 如果我有一些“嵌套”数据类型,例如在此示例代码中:

data Place = Country
           | State
           | City String
           deriving Show

data State = California
           | NewYork
           deriving Show

data Country = USA
             | Canada
             deriving Show

I can legally make a list such as [USA, Canada] of type [Country], or [California, NewYork] of type [State], or [City "a", City "b"] of type [Place]. 我可以合法地制作[国家]类型的[美国,加拿大]或[州]类型的[加利福尼亚州,纽约州]或[地方]类型的[城市“a”,城市“b”]等列表。

What do I have to do to make a list such as [USA, NewYork]? 如何制作像[USA,NewYork]这样的清单,我该怎么办? NewYork is a State which is a Place, and USA is a Country which is a Place, but ghci sees USA so it assumes I am making a list of Countrys (and NewYork is a State, so the list fails). 纽约是一个地方的国家,美国是一个地方的国家,但是ghci看到美国所以它假设我正在制作一个国家的名单(而纽约是一个州,所以列表失败)。

I think I need some way to cast a Country or State to a Place, but I'm at a loss on how to accomplish this. 我想我需要某种方式将一个国家或州置于一个地方,但我对如何实现这一目标感到茫然。

I'm trying to avoid throwing the data contained within State and Country into the Place type, which I know would make it work, but I've got a decent amount of real data that I'd rather not jumble up like that. 我试图避免将State和Country中包含的数据放入Place类型,我知道这会使它工作,但是我有相当数量的实际数据,我宁愿不要那样混淆。

Here's a little more output that led me to figure out the problem: 这是一个更多的输出,让我找出问题:

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

This seems to imply that the word "State" is a valid constructor for Place, and that the data State refers to a value of only California or NewYork. 这似乎意味着“State”这个词是Place的有效构造函数,而数据State指的是只有California或NewYork的值。

If you change the program slightly, to: 如果稍微更改程序,请:

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

data State = California
           | NewYork
           deriving Show

data Country = USA
             | Canada
             deriving Show

then you can make a list such as [Country USA, State NewYork] which is properly of type [Place]. 那么你可以制作一个列表,如[Country USA,State NewYork],它的类型[Place]。 Using the same word twice as in the first example does not "bind" the State type together in the way I had thought it would. 使用与第一个示例中相同的单词两次不会以我认为的方式将State类型“绑定”在一起。

Of course, using the constructor State State is just a matter of preference, I could just as easily do AmericanState State within the Place type if I were so inclined. 当然,使用构造函数State State只是一个偏好问题,如果我这么倾向的话,我可以很容易地在Place类型中做AmericanState State

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

See the GHC user guide # 7.4.4 Existentially quantified data constructors for some restrictions with this approach. 有关此方法的一些限制,请参阅GHC用户指南#7.4.4存在量化数据构造函数


There's a in-depth study of making usable heterogeneous collections in Haskell. 有一个深入的研究,在Haskell中制作可用的异构集合。

Strongly typed heterogeneous collections 强类型的异构集合

A heterogeneous collection is a datatype that is capable of storing data of different types, while providing operations for look-up, update, iteration, and others. 异构集合是一种数据类型,能够存储不同类型的数据,同时提供查找,更新,迭代等操作。 There are various kinds of heterogeneous collections, differing in representation, invariants, and access operations. 存在各种异构集合,表示,不变量和访问操作不同。 We describe HList --- a Haskell library for strongly typed heterogeneous collections including extensible records. 我们描述了HList ---一个用于强类型异构集合的Haskell库,包括可扩展记录。 We illustrate HList's benefits in the context of type-safe database access in Haskell. 我们在Haskell中的类型安全数据库访问的上下文中说明了HList的好处。 The HList library relies on common extensions of Haskell 98. Our exploration raises interesting issues regarding Haskell's type system, in particular, avoidance of overlapping instances, and reification of type equality and type unification. HList库依赖于Haskell 98的常见扩展。我们的探索提出了有关Haskell类型系统的有趣问题,特别是避免重叠实例,以及类型相等和类型统一的具体化。

You're building a heterogeneous list (ie the list holds values of different types). 您正在构建异构列表(即列表包含不同类型的值)。 Such a structure can be statically or dynamically typed. 这种结构可以是静态或动态类型的。 Either way, as long as we know the value supports a particular interface, we can use it in a list wrapped. 无论哪种方式,只要我们知道值支持特定接口,我们就可以在列表中使用它。

The nicest approach, IMO, is via existential typing, as ephemient shows: 最好的方法,IMO,通过存在性打字,如ephemient显示:

  • all values support the Show interface 所有值都支持Show界面
  • anything that supports Show can be put in the list 任何支持Show的东西都可以放在列表中
  • the type system guarantees you can't break the abstraction 类型系统保证你不能打破抽象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM