Stranger
Stranger

Reputation: 862

collatz-list implementation using haskell

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?

Upvotes: 2

Views: 2621

Answers (3)

David
David

Reputation: 8395

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

Upvotes: 0

hammar
hammar

Reputation: 139930

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)

Upvotes: 4

dreamcrash
dreamcrash

Reputation: 51633

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)

Upvotes: 2

Related Questions