要自己轻松回答此类问题,您需要轻松理解 Haskell 的代数数据类型定义:
-- v a type being defined
data Bin =
B Bin
-- ^ ^ the type of the argument to the data constructor `B`
-- ^ the name of the data constructor function `B`: B :: Bin -> Bin
-- (read: B is of type Bin -> Bin, i.e. a function
-- taking a Bin type value and producing a Bin type value)
| C [Int]
-- ^ ^ the type of the argument to the data constructor `C`
-- ^ the name of the data constructor function `C`: C :: [Int] -> Bin
-- (read: C is of type [Int] -> Bin, i.e. a function
-- taking a list of Int values and producing a Bin type value)
这意味着,我们可以使用以下两种方式之一创建Bin 类型的数据:
- 首先,我们可以调用一个名为
B 的函数,其参数为 Bin 类型的值。
- 其次,我们可以调用一个名为
C 的函数,它有一个参数,一个 [Int] 类型的值,一个整数列表。
第二种方法简单明了:只需使用任何整数列表,例如C [1] 或C [4,3,2]
x1 :: Bin -- read: `x1` is of type `Bin`
x1 = C [1] -- or,
但是第一个呢?我们需要使用Bin 类型的值作为参数:
x1 = B x2
但是我们在哪里可以获得x2?我们正在创建一个Bin,它希望我们给它一个Bin?这是恶性循环吗?
不!因为我们有第二种方法来创建Bin 值:
x2 = C [2] -- x1 = B (C [2])
但我们也可以在这里使用第一个:
x2 = B x3 -- x1 = B (B x3)
那么x3 呢?同理,
x3 = C [3] -- x1 = B (B (C [3])) -- or,
x3 = B x4 -- x1 = B (B (B x4))
和
x4 = C [4] -- x1 = B (B (B (C [4]))) -- or,
x4 = B x5 -- x1 = B (B (B (B x5)))
看到了吗? Bin 类型的有效值由 B 构造函数的嵌套链组成,在链的最底部带有 C [...]。正确的?数据类型定义用作生成该类型有效项的语法。
现在很容易回答您的问题:
C [ ] : - 这是一个嵌套的B 链,底部有C? : __
B (B C [2]) : - 这是一个嵌套的B 链,底部有C? : __
B (C [1..5]) : - 这是一个嵌套的B 链,底部有C? : __
B (B (B (C [2,3]))) : - 这是一串嵌套的B,底部有C? : __
相同规则的重复应用称为recursion,因此该数据类型Bin是一个recursive数据类型,其定义中有两个子句:递归子句和基子句。
哪个是哪个?