Haskell Collatz Conjecture In an attempt to begin properly programming in Haskell, I wrote two functions for calculating numbers and sequences with Collatz's conjecture. I also commented the program quite a lot, because it helps me with my remembering of certain things.

-- The Collatz sequence takes in a number, and either
-- divides by 2 if it is even, or
-- multiplies it by 3 and adds 1 if it is odd.
-- The famous Collatz conjecture asks whether the sequence,
-- from any positive initial value, will reach 1.


-- a guard expression is used for the 'collatz' variable,
-- used for finding the next number in a sequence. This is
-- neater than if / else if.
collatz n
    | n `mod` 2 == 0 = n `div` 2 -- if n is even, return n / 2
    | otherwise = 3 * n + 1 -- else return 3n + 1

-- another guard expression, this time for the variable that
-- generates whole sequences. it is recursive, and takes 
-- advantage of the 'collatz' variable too.
cltzList n
    | n &lt;= 0 = error "The number must be positive."
    | n == 1 = [n] -- if n is 1 return n:[]
    | otherwise = n:cltzList (collatz n) -- else, recursive-call


How have I done? Are there any big mistakes, or small things I can improve?
There's nothing wrong with your code in terms of functionality, but there are a number of things we can do to make it more stylish and idiomatic.

The #1 most important thing you have missed is to always provide a type signature for top-level definitions. Just reading the type signature of a function can often give you an intuition as to what that function will do (think of IO actions, or higher order functions) or confirm that what you've written actually does something like what you're expecting after you've called the compiler to check your work.

collatz :: Int -&gt; Int
cltzList :: Int -&gt; [Int]


There are a few small tweaks to your definitions that we should make to come in line with good Haskell style, these won't impact functionality but help your function definitions to read more like English definitions instead of instructions for a computer.

When checking to see if a number is even, use the function even instead of checking the value in modulo 2. The definition of even may be doing the same operation under the hood but using even expresses your intent instead of the method. Changes like these will improve the readability of your code in larger projects remarkably. (Additionally, abstracting out even allows the implementer of that function to change the definition to be more efficient without requiring any changes to your code, e.g., even may check the least significant bit instead of performing any mathematical operation at all.)

collatz n | even n = n `div` 2


When calling error, you should always include the module and function name so that users of your code know what function the error actually originated from. I.e, error "Collatz.cltzList: The number must be positive" That way if someone calls your function with a negative number they see this

*** Exception: Collatz.cltzList: The number must be positive


instead of this

*** Exception: The number must be positive.


On this line | n == 1 = [n] I would change [n] to [1]. That's the only value n will ever be, so it's better to be explicit than to be clever.

You have far too many comments that have little to no value. For instance, you can assume that unless you're writing an "Intro to Haskell" book your readers will know what pattern guards are and so you don't need to explain what they are or why you used them.

And finally in my version below I've cleaned up the alignment with liberal use of whitespace. This is mostly an aesthetic effect but I find beautiful code easier to read than otherwise, and this is not an uncommon style in Haskell code.

-- Implements the Collatz sequence.
-- 
--        n / 2     if n is even
-- c(n) = 
--        3 * n + 1 if n is odd

module Collatz where

collatz :: Int -&gt; Int
collatz n | even n    = n `div` 2
          | otherwise = 3 * n + 1

-- Produces the Collatz sequence for a given non-zero natural number
collatzList :: Int -&gt; [Int]
collatzList n | n &lt;= 0    = error "Collatz.collatzList: n must be positive"
              | n == 1    = 1 : []
              | otherwise = n : collatzList (collatz n)