【问题标题】:Haskell Data TypesHaskell 数据类型
【发布时间】:2018-11-29 08:23:17
【问题描述】:

下面定义的 Bin 数据类型的哪个值不是?

data Bin = B Bin | C [ Int]

a)C [ ]

b)B ( B C [ 2])

c)B ( C [ 1..5])

d)B (B (B (C[2,3])))

【问题讨论】:

  • 您可以尝试在ghci中输入类型定义和不同的值来自己解决
  • 我用拥抱但我无法识别

标签: haskell recursion grammar algebraic-data-types recursive-datastructures


【解决方案1】:

要自己轻松回答此类问题,您需要轻松理解 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数据类型,其定义中有两个子句:递归子句和基子句。

哪个是哪个?

【讨论】:

  • 非常感谢☺
  • 不客气。那么,哪个是哪个?你能告诉?数据类型定义中的哪个子句是递归的,哪个不是?
  • 递归定义
  • 是的,但它有两个子句 - 一个用于 B,另一个用于 C。其中哪个是递归的,哪个是基本情况?
【解决方案2】:

通过使用ghci 并简单地输入代码sn-ps,您将看到哪些值被接受:

Prelude> data Bin = B Bin | C [ Int]
Prelude> a = C [ ]
Prelude> b = B ( B C [ 2])

<interactive>:3:9: error:
    • Couldn't match expected type ‘[Integer] -> Bin’
                  with actual type ‘Bin’
    • The function ‘B’ is applied to two arguments,
      but its type ‘Bin -> Bin’ has only one
      In the first argument of ‘B’, namely ‘(B C [2])’
      In the expression: B (B C [2])

<interactive>:3:11: error:
    • Couldn't match expected type ‘Bin’
                  with actual type ‘[Int] -> Bin’
    • Probable cause: ‘C’ is applied to too few arguments
      In the first argument of ‘B’, namely ‘C’
      In the first argument of ‘B’, namely ‘(B C [2])’
      In the expression: B (B C [2])
Prelude> c = B ( C [ 1..5])
Prelude> d = B (B (B (C[2,3])))

【讨论】:

  • 非常感谢☺
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多