使用haskell进行collat​​z-list实现

时间:2012-11-25 22:55:14

标签: haskell

我正在尝试使用Haskel实现collat​​z-list: 这是我的代码:

collatz n
     | mod n 2 == 0 = div n 2
     | otherwise =  3 * n + 1


collatzList n
        | n < 1 = error "Cannot have negative number"
collatzList
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)

我得到的错误信息是: 输入`collat​​zList'解析错误 [1/1]编译Main(exer.hs,解释) 失败,模块加载:无。

有人能告诉我为什么收到这条消息吗?

3 个答案:

答案 0 :(得分:4)

我得到了不同的错误(使用GHC 7.4.1):

> :load "/tmp/C.hs"
[1 of 1] Compiling Main             ( /tmp/C.hs, interpreted )

/tmp/C.hs:9:11: Not in scope: `n'

/tmp/C.hs:9:21: Not in scope: `n'

/tmp/C.hs:10:23: Not in scope: `n'

/tmp/C.hs:10:46: Not in scope: `n'
Failed, modules loaded: none.

这是因为您在n的第二个等式中忘记了collatzList参数。您可以添加此参数

collatzList n
        | n < 1 = error "Cannot have negative number"
collatzList n -- the n was missing here
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)

或者,由于左侧现在是相同的,您可以简单地将它与第一个一起加入:

collatzList n
        | n < 1 = error "Cannot have negative number"
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)

答案 1 :(得分:2)

您正在重新定义collatzList

collatzList
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)

这样做:

collatz n
     | mod n 2 == 0 = div n 2
     | otherwise =  3 * n + 1

collatzList n
        | n < 1 = error "Cannot have negative number"
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)

答案 2 :(得分:0)

生成仅依赖于先前值的值列表是unfoldr函数(Data.List.unfoldr)的典型应用程序:

import Data.List (unfoldr)
collatzList = unfoldr nextCollatz
      where nextCollatz n | n <= 0    = Nothing
                          | n == 1    = Just (1,0)
                          | even n    = Just (n, n `quot` 2)
                          | otherwise = Just (n, 3*n+1)

unfoldr f x0获取起始值x0,并向其应用函数f。如果f x0Nothing,则算法终止;如果是Just (push, next),则会将push添加到结果列表中,并使用next作为x0的新值。另一个例子,使用展开式生成最大为100的正方形:

import Data.List (unfoldr)
squareList = unfoldr pow2
      where pow2 n | n > 100   = Nothing
                   | otherwise = Just (n, 2*n)
                   -- "Add n to the result list,
                   -- start next step at 2*n."

(关于error的强制性评论:通常最好让函数返回一些虚拟值。例如,在上面的Collat​​z函数中,非正整数的结果是空列表而不是异常。)