2

I am trying to implement collatz-list using Haskel: Here's my code:

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)

The error message I am getting is this: parse error on input `collatzList' [1 of 1] Compiling Main ( exer.hs, interpreted ) Failed, modules loaded: none.

Can anyone tell me why I am getting this message?

Stranger
  • 864
  • 4
  • 21
  • 48

3 Answers3

4

I get different errors (using 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.

This is because you forgot the n argument in your second equation for collatzList. You can either add this argument

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

or, since the left hand sides are now the same, you can simply join it with the first one:

collatzList n
        | n < 1 = error "Cannot have negative number"
        | n == 1 = [n]
        | otherwise = n:collatzList (collatz n)
hammar
  • 138,522
  • 17
  • 304
  • 385
  • 2
    @user1462452: Yes, this compiles fine on GHC 7.4.1. Given the error message you got, I suggest double-checking your indentation. Perhaps you're mixing tabs with spaces, which has a tendency of causing "invisible" syntax errors like this. – hammar Nov 25 '12 at 23:14
2

You are redefining collatzList.

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

do this:

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)
dreamcrash
  • 47,137
  • 25
  • 94
  • 117
0

Generating a list of values that only depend on the previous value is a typical application for the unfoldr function (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 takes a starting value x0, and applies a function f to it. If f x0 is Nothing, the algorithm terminates; if it is Just (push, next), it adds push to the result list, and uses next as the new value for x0. Another example, generating squares up to 100 using unfoldr:

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."

(And the obligatory remark about error: it's usually better to make the function return some dummy value. In my Collatz function above for example, the result for non-positive integers is an empty list instead of an exception.)

David
  • 8,275
  • 5
  • 26
  • 36