更新时间:2023-11-23 21:15:10
Apart from the fact that inits
and tails
aren't found in Prelude
, you can define your function as such:
yourFunction :: [a] -> [[a]]
yourFunction = filter (not . null) . concat . map inits . tails
This is what it does, step by step:
tails
gives all versions of a list with zero or more starting elements removed: tails [1,2,3] == [[1,2,3],[2,3],[3],[]]
map inits
applies inits
to every list given by tails
, and does exactly the opposite: it gives all versions of a list with zero or more ending elements removed: inits [1,2,3] == [[],[1],[1,2],[1,2,3]]
concat
: it applies (++)
where you see (:)
in a list: concat [[1,2],[3],[],[4]] == [1,2,3,4]
. You need this, because after map inits . tails
, you end up with a list of lists of lists, while you want a list of lists.filter (not . null)
removes the empty lists from the result. There will be more than one (unless you use the function on the empty list).You could also use concatMap inits
instead of concat . map inits
, which does exactly the same thing. It usually also performs better.
Edit: you can define this with Prelude
-only functions as such:
yourFunction = concatMap inits . tails
where inits = takeWhile (not . null) . iterate init
tails = takeWhile (not . null) . iterate tail