3
votes

I want to create a Haskell function that prints the suffixes of a list:

The function should do the following:

> suffixes "123"
["23","3",""]
> suffixes "1"
[""]

I have written the following code:

suffixes :: [a] -> [[a]]
suffixes []         = [] : []
suffixes f@(_:t) = f: suffixes t 

The function prints the entered string or character as a suffix and I want to remove it so when I enter "123" it should print as above.

Can you help me solve this so that it does not print the entered string as a suffix.

1
If this was for homework or practice, then @WillemVanOnsem's answer seems like the right approach, but in actual code, you could consider writing suffixes = tail . tails using tails from Data.List.K. A. Buhr

1 Answers

4
votes

There are basically two ways to do this. The first approach slightly changes how the function works: in that case the base-case returns an empty list, and the recursive case yields t instead of f:

suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:t) = t : suffixes t

This works since t is the tail of the list, so it is the list, but without the first element. We thus yield this element, and perform recursion on the tail t as well, until we reach the empty list. Since this empty list was already "yielded" by the recursive case, we thus do not yield it in the basecase.

Or we can just keep the old suffixes function (but rename it to for example go), and let the outer function "pre-processes" the list by "popping" an element:

suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:xs) = go xs
    where go [] = [] : []
          go f@(_:t) = f: go t

Note that for an empty string, there are no proper suffixes, hence we return an empty list.

This then yield the expected results:

Prelude> suffixes ""
[]
Prelude> suffixes "a"
[""]
Prelude> suffixes "ab"
["b",""]
Prelude> suffixes "abc"
["bc","c",""]
Prelude> suffixes "123abc"
["23abc","3abc","abc","bc","c",""]