Haskell 99, Problems 1-10 (simple list processing)
Solutions 1 and 2 are fine.

Solution 3: Find the Kth element of a list

The error message for 3 is a bit misleading: you can also get the error if the requested index is beyond the end of the list.  Strictly speaking, it should be an error to request a non-positive index as well.

Solution 4: Find the number of elements of a list

You should not need a helper function.

myLength :: [a] -&gt; Int
myLength [] = 0
myLength (x:xs) = 1 + myLength xs


However, as @Franky points out, using a helper function can make it tail-recursive.

Solution 5: Reverse a list

You could write it as myReverse (x:xs) = (myReverse xs) ++ x, but it is much more efficient the way you wrote it using a helper function.  The helper should be scoped using a where clause (or let … in, which does the same thing).  It is customary to name trivial helper functions using the myReverse' convention.

myReverse :: [a] -&gt; [a]
myReverse xs = myReverse' xs []
  where
    myReverse' []     rev = rev
    myReverse' (x:xs) rev = myReverse' xs (x:rev)


Solution 7: Flatten a nested list structure.

No helper is necessary.

data NestedList a = Elem a | List [NestedList a]

flatten :: NestedList a -&gt; [a]
flatten (Elem x)      = [x]
flatten (List [])     = []
flatten (List (x:xs)) = flatten x ++ flatten (List xs)


Solution 8: Eliminate consecutive duplicated list elements

Again, no helper or accumulator is necessary.  Furthermore, you should avoid ++, as it works by inefficiently walking to the end of its LHS argument.

compress :: Eq a =&gt; [a] -&gt; [a]
compress []     = []
compress (x:[]) = [x]
compress (x:y:zs)
  | x == y      = compress (y:zs)
  | otherwise   = x : compress (y:zs)


Problem 9: Pack consecutive duplicates of list elements into sublists

I don't think that packing an empty list should be an error.  Rather it should just return an empty list.

My advice is similar to the above.  I think that a helper function is needed, but not in that way.

pack :: Eq a =&gt; [a] -&gt; [[a]]
pack [] = []
pack (x:xs) = pack' [x] xs
  where
    pack' run []  = [run]
    pack' run@(r:_) (x:xs)
      | x == r    = pack' (x:run) xs
      | otherwise = run : pack' [x] xs


Problem 10: Run-length encoding of a list

Again, I don't think that encoding an empty list should be an error.

The implementation would read more nicely, in my opinion, using a list comprehension and better naming.

encode :: Eq a =&gt; [a] -&gt; [(Int, a)]
encode xs = [(length run, head run) | run &lt;- pack xs]




In summary, accumulators are sometimes the right approach (as in myReverse), but often they are harmful.  Before using one, think hard about whether it is necessary and efficient.