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

How do you create and use datatypes in Haskell?

我是哈斯克尔的新手。但我真的很喜欢。我一直在阅读,学习哈斯克尔和现实世界哈斯克尔和实践。我在"学习你"一本哈斯克尔的书中的"功能性解决问题"部分,我需要有人向我解释以下内容:

1
2
     data Node = Node Road Road | EndNode Road  
     data Road = Road Int Node

问题:

  • 这是某种递归数据类型创建吗?
  • 为什么我不能做:节点"a""b"并获取有效的节点类型?当我尝试一些东西的时候,我可能会犯一个错误,说haskell不能将[char]与预期的道路匹配,我理解这一点。但是如果没有road int节点,就无法创建节点x y。我以为road是string的同义词,但由于它没有被声明,所以肯定不是。如果有人读了这本书并理解了这一点,请解释这些数据类型的含义,并在可能的情况下提供示例。

编辑:有问题的章节>>希思罗到伦敦问题


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

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

1
2
3
nodeA, nodeB :: Node
nodeA = EndNode (Road 99 nodeB)
nodeB = EndNode (Road 99 nodeA)

注意nodea的定义是如何引用nodeb的,反之亦然。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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等的相互递归。

我已经把这些路写了下来,但是如果你愿意的话,你当然可以把它们都命名为:

1
2
roadA1ToB1 :: Road
roadA1ToB1 = Road 30 b1

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