It's been over a year now but no correct answers were given so here's my take on it.

Let's start with the type signature:

tails' :: [a] -> [[a]]

This sugests that tails' should return a list-of-lists. The terminal case you syggested is just an empty list. Change it to:

tails' [] = [[]]

Now, the general case. Let's assume that our tails' works the way we want it to:

tails' [] -> [[]] tails' [1] -> [[1], []] tails' [2,1] -> [[2,1], [1], []] tails' [3,2,1] -> [[3,2,1], [2,1], [1], []]

As we can see, we want to include the original list and the empty list. This means that given an input list xs , we want to concatenate xs onto something else.

But what's that something else? Let's do a bit of pseudo-haskell math:

let A = tails' [3,2,1] = [[3,2,1], [2,1], [1], []] let B = tails' [2,1] = [[2,1], [1], []] => A = [[3,2,1], B] -- (1) tail [3,2,1] == [2,1] => B = tails' (tail [3,2,1]) -- (2) By (1) and (2) A = [[3,2,1], tails' (tail [3,2,1])] => tails' [3,2,1] = [[3,2,1], tails' (tail [3,2,1])] -- (3) By replacing [3,2,1] in (3) with xs tails' xs = [xs, tails' (tail xs)]

Translating all this into Haskell gives us: