使用haskell进行collatz-list实现

collatz-list implementation using haskell

我尝试使用haskel实现collatz列表:这是我的代码:

1
2
3
4
5
6
7
8
9
10
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)

我收到的错误消息是:输入"collatzlist"时出现分析错误[第1页,共1页]编译主(练习hs,解释)失败,模块已加载:无。

有人能告诉我为什么要收到这个信息吗?


i get(使用不同的状态:7.4.1 GHC的)

1
2
3
4
5
6
7
8
9
10
11
> :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.

这是因为你忘了你的论点是在第二个ncollatzList方程。你可以添加这一论点。

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

或者,因为左手边是现在你可以简单的连接是一样的,它与第一个:

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


你是redefining collatzList

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

这样做:

1
2
3
4
5
6
7
8
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)


生成列表的值只取决于这是在以前的值是一个典型的应用程序的功能(unfoldrData.List.unfoldr):

1
2
3
4
5
6
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需要从价值和功能fx0,适用于它。如果是Nothingf x0,算法terminates;如果它是Just (push, next)push,它添加到列表,和使用作为x0next新价值。另一个例子,使用unfoldr产生多达100平方:

1
2
3
4
5
6
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它通常更好的做一些虚拟函数返回值。在Collatz功能我上面的做法的结果是一个非营利的正整数而不是在空列表)的异常。