如何在Haskell中创建和使用数据类型?

时间:2015-07-16 02:00:19

标签: haskell

我是Haskell的绝对新手。但我真的很喜欢它。我一直在阅读了解你一个Haskell 真实世界Haskell 并一直在练习。我在了解你一个Haskell 一书的功能解决问题部分,我需要有人向我解释以下内容:

     data Node = Node Road Road | EndNode Road  
     data Road = Road Int Node 

问题:

  • 这是一种递归数据类型的创建吗?
  • 为什么我不能这样做:节点“A”“B”并获得有效的节点类型?当我尝试某些东西时,我可以发错误说Haskell无法与预期道路匹配[Char],我理解这一点。但是,如果没有 Road Int Node ,我无法创建 Node X Y 。我认为Road是String的类型同义词,但因为它没有声明它肯定不是。如果有人读过这本书并理解了这一点,请解释数据类型的含义并提供示例,如果可能的话。

修改:The Chapter In Question >> Heathrow to London problem

1 个答案:

答案 0 :(得分:2)

是的,这些是相互递归的数据类型。

要创建这些类型的值,您可能也会使用递归。例如,这是一个最小的道路系统 - 两个节点,每个节点允许您开车到另一个:

nodeA, nodeB :: Node
nodeA = EndNode (Road 99 nodeB)
nodeB = EndNode (Road 99 nodeA)

注意nodeA的定义如何引用nodeB,反之亦然。

如果我正确阅读了本书中的例子,可以这样写:

aRoad, bRoad :: Road
aRoad = Road 50 a1
bRoad = Road 10 b1

a1, a2, a3, a4 :: Node
a1 = Node (Road 5 a2) (Road 30 b1)
a2 = Node (Road 40 a3) (Road 20 b2)
a3 = Node (Road 10 a4) (Road 25 b3)
a4 = EndNode (Road 0 b4)

b1, b2, b3, b4 :: Node
b1 = Node (Road 90 b2) (Road 30 a1)
b2 = Node (Road 2 b3) (Road 20 a2)
b3 = Node (Road 8 b4) (Road 25 a3)
b4 = EndNode (Road 0 a4)

再次注意交叉道路的a1和b1,a2和b2等的相互递归。

我已经将这些道路写成了内联,但当然如果您愿意,可以将它们全部命名为:

roadA1ToB1 :: Road
roadA1ToB1 = Road 30 b1

如果你这样做,定义的循环将涉及其中的四个 - (节点)a1的定义将使用roadA1ToB1,这将使用b1,这将使用roadB1ToA1,这将使用a1