基本上有两种方法可以做到这一点。第一种方法稍微改变了函数的工作方式:在这种情况下,基本情况返回一个空列表,递归情况产生t而不是f:
suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:t) = t : suffixes t
这是有效的,因为它是列表t的尾部,所以它是列表,但没有第一个元素。因此,我们产生了这个元素,并对尾部执行递归t,直到我们到达空列表。由于这个空列表已经被递归案例“产生”,因此我们不会在基本案例中产生它。
或者我们可以只保留旧suffixes函数(但将其重命名为 example go),并让外部函数通过“弹出”一个元素来“预处理”列表:
suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:xs) = go xs
where go [] = [] : []
go f@(_:t) = f: go t
请注意,对于空字符串,没有适当的后缀,因此我们返回一个空列表。
这会产生预期的结果:
Prelude> suffixes ""
[]
Prelude> suffixes "a"
[""]
Prelude> suffixes "ab"
["b",""]
Prelude> suffixes "abc"
["bc","c",""]
Prelude> suffixes "123abc"
["23abc","3abc","abc","bc","c",""]