Search code examples
haskell

Implementing inits function in Haskell


I'm working on an assignment in Haskell where I need to implement the inits function. So far, I have the following code:

inits [] = [[]]
inits (x:xs) =  [x]: inits (xs)

However, when I run this with the input inits [1,2], I get the following output: [[1], [2], []]

This doesn't seem right, as the expected output for inits [1, 2] should be:

[[], [1], [1, 2]]

I understand that inits should return all initial segments of the list, but my code isn't doing that correctly. Could someone point me in the right direction on how I can adjust my function to achieve the correct output?

I'm still learning Haskell, so any tips or explanations would be greatly appreciated. Thank you!


Solution

  • As an alternative to explicit recursion, an approach to writing tails would be to use scanr, which works much like foldr but saves the intermediate results as a list.

    Prelude> scanr (:) [] [1,2,3]
    [[1,2,3],[2,3],[3],[]]
    Prelude> scanr (:) [] $ tail [1,2,3]
    [[2,3],[3],[]]
    Prelude> tails = scanr (:) [] . tail
    Prelude> tails [1,2,3]
    [[2,3],[3],[]]
    

    Implementing inits can similarly be achieved using scanl:

    Prelude> scanl (flip (:)) [] [1,2,3]
    [[],[1],[2,1],[3,2,1]]
    Prelude> map reverse $ scanl (flip (:)) [] [1,2,3]
    [[],[1],[1,2],[1,2,3]]
    Prelude> inits = map reverse . scanl (flip (:)) []
    Prelude> inits [1,2,3]
    [[],[1],[1,2],[1,2,3]]