首页 > 解决方案 > 使用预定义变量的 Haskell 代码

问题描述

谁能告诉我为什么 Haskell 中的以下代码不起作用?

a = 5
foo :: Int -> Int -> Int
foo a 0 = 0
foo a b = a + foo a (b - 1)
  where
    a = a + 1

标签: haskell

解决方案


在 Haskell 中,变量在其定义期间处于范围内,因此在 中a = a + 1a是指自身。如果我们重命名代码中的变量,使所有变量都有唯一的名称,它将如下所示:

a1 = 5
foo :: Int -> Int -> Int
foo _ 0 = 0
foo a2 b = a3 + foo a3 (b - 1)
  where
    a3 = a3 + 1

所以这里的问题是它a3 = a3 + 1是无限递归的——a3不能等于它自己的值加一。也a2从未使用过。

你说你希望它引用参数的值,所以现在变量有不同的名称,我们可以很容易地解决这个问题:

foo :: Int -> Int -> Int
foo _ 0 = 0
foo a2 b = a3 + foo a3 (b - 1)
  where
    a3 = a2 + 1

请注意,我a1这次省略了,因为它与foo功能无关。我们也可以去掉where并只内联a2 + 1部分(并重命名a2为,a因为不再有多个):

foo :: Int -> Int -> Int
foo _ 0 = 0
foo a b = (a + 1) + foo (a + 1) (b - 1)

推荐阅读