Haskell数据类型列表

Mar*_*off 6 haskell types

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

data Place = Country
           | State
           | City String
           deriving Show

data State = California
           | NewYork
           deriving Show

data Country = USA
             | Canada
             deriving Show
Run Code Online (Sandbox Code Playgroud)

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

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

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

我试图避免将State和Country中包含的数据放入Place类型,我知道这会使它工作,但是我有相当数量的实际数据,我宁愿不要那样混淆.

Mar*_*off 12

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

*Main> [State, State]
[State,State]
*Main> :t State
State :: Place
*Main> :t NewYork
NewYork :: State
Run Code Online (Sandbox Code Playgroud)

这似乎意味着"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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 哦,那是你磕磕绊绊的?是的,构造函数和类型都以大写字符开头,但是在不同的名称空间中. (3认同)

eph*_*ent 7

{-# LANGUAGE ExistentialQuantification #-}
data GenericPlace = forall a. Show a => GenericPlace a
places :: [GenericPlace]
places = [GenericPlace USA, GenericPlace NewYork]
Run Code Online (Sandbox Code Playgroud)

有关此方法的一些限制,请参阅GHC用户指南#7.4.4存在量化数据构造函数.


有一个深入的研究,在Haskell中制作可用的异构集合.

强类型的异构集合

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