Given a Haskell list, return all sub-lists obtained by removing one element











up vote
9
down vote

favorite
2












I am trying to write a Haskell function which takes a list ls and returns all sub-lists obtained by removing one element from ls. An additional constraint is that the returned list of lists must be in the order of the missing element.



Here is what I have. I know there must be a simpler solution.



subOneLists :: [a] -> [[a]]
subOneLists ls = let helper :: [a] -> [a] -> [[a]] -> [[a]]
helper _ ss = ss
helper ps (x:xs) ss = helper ps' xs ss'
where ps' = ps ++ [x]
ss' = ss ++ [ps ++ xs]
in helper ls

λ> subOneLists [1, 2, 3, 4]
[[2,3,4],[1,3,4],[1,2,4],[1,2,3]]









share|improve this question









New contributor




Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    9
    down vote

    favorite
    2












    I am trying to write a Haskell function which takes a list ls and returns all sub-lists obtained by removing one element from ls. An additional constraint is that the returned list of lists must be in the order of the missing element.



    Here is what I have. I know there must be a simpler solution.



    subOneLists :: [a] -> [[a]]
    subOneLists ls = let helper :: [a] -> [a] -> [[a]] -> [[a]]
    helper _ ss = ss
    helper ps (x:xs) ss = helper ps' xs ss'
    where ps' = ps ++ [x]
    ss' = ss ++ [ps ++ xs]
    in helper ls

    λ> subOneLists [1, 2, 3, 4]
    [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]









    share|improve this question









    New contributor




    Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      9
      down vote

      favorite
      2









      up vote
      9
      down vote

      favorite
      2






      2





      I am trying to write a Haskell function which takes a list ls and returns all sub-lists obtained by removing one element from ls. An additional constraint is that the returned list of lists must be in the order of the missing element.



      Here is what I have. I know there must be a simpler solution.



      subOneLists :: [a] -> [[a]]
      subOneLists ls = let helper :: [a] -> [a] -> [[a]] -> [[a]]
      helper _ ss = ss
      helper ps (x:xs) ss = helper ps' xs ss'
      where ps' = ps ++ [x]
      ss' = ss ++ [ps ++ xs]
      in helper ls

      λ> subOneLists [1, 2, 3, 4]
      [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]









      share|improve this question









      New contributor




      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I am trying to write a Haskell function which takes a list ls and returns all sub-lists obtained by removing one element from ls. An additional constraint is that the returned list of lists must be in the order of the missing element.



      Here is what I have. I know there must be a simpler solution.



      subOneLists :: [a] -> [[a]]
      subOneLists ls = let helper :: [a] -> [a] -> [[a]] -> [[a]]
      helper _ ss = ss
      helper ps (x:xs) ss = helper ps' xs ss'
      where ps' = ps ++ [x]
      ss' = ss ++ [ps ++ xs]
      in helper ls

      λ> subOneLists [1, 2, 3, 4]
      [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]






      haskell






      share|improve this question









      New contributor




      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 20 hours ago









      200_success

      127k15148410




      127k15148410






      New contributor




      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 22 hours ago









      Paul

      1484




      1484




      New contributor




      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          13
          down vote



          accepted










          Here's a simpler way to implement it:



          subOneLists :: [a] -> [[a]]
          subOneLists =
          subOneLists (x:xs) = xs : map (x :) (subOneLists xs)





          share|improve this answer





















          • This is really clever
            – Paul
            21 hours ago






          • 3




            this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
            – Will Ness
            12 hours ago




















          up vote
          5
          down vote













          List as an abstract concept can have many representations.



          In particular, with a list being represented by its "zipper" - a pairing of a reversed prefix and a suffix, it becomes possible to have a linear solution to this problem, as opposed to the quadratic one which is unavoidable with the plain linear representation :



          picks :: [a] -> [([a], [a])]
          picks =
          picks (x:xs) = go [x] xs
          where
          go pref suff@(x:xs) = (pref,suff) : go (x:pref) xs
          go pref = [(pref,)]


          Using this, your problem becomes



          foo = map ((a,b) -> revappend (tail a) b) . picks

          revappend a b = foldl (flip (:)) b a


          This is of course again quadratic, but maybe you could keep the prefixes reversed, to stay linear:



          import Control.Arrow (first)

          foo' = map (first tail) . picks -- or,
          -- = map ((x,y) -> (tail x, y)) . picks





          share|improve this answer






























            up vote
            3
            down vote













            Look out for standard functions that can help you!



            Prelude Data.List> let subOneLists ls = zipWith (++) (inits ls) (tail $ tails ls)
            Prelude Data.List> subOneLists [1, 2, 3, 4]
            [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]


            This uses the fact that the inits- and tails-elements at corresponding index always recombine to the original list, but with a variably splitting point:



            Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tails ls))
            (,[0,1,2,3,4,5,6,7])
            ([0],[1,2,3,4,5,6,7])
            ([0,1],[2,3,4,5,6,7])
            ([0,1,2],[3,4,5,6,7])
            ([0,1,2,3],[4,5,6,7])
            ([0,1,2,3,4],[5,6,7])
            ([0,1,2,3,4,5],[6,7])
            ([0,1,2,3,4,5,6],[7])
            ([0,1,2,3,4,5,6,7],)


            If you now “shift up” that tails, by dropping its head, you effectively lose the head of each of the contained lists:



            Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tail $ tails ls))
            (,[1,2,3,4,5,6,7])
            ([0],[2,3,4,5,6,7])
            ([0,1],[3,4,5,6,7])
            ([0,1,2],[4,5,6,7])
            ([0,1,2,3],[5,6,7])
            ([0,1,2,3,4],[6,7])
            ([0,1,2,3,4,5],[7])
            ([0,1,2,3,4,5,6],)


            And that can just be ++ combined with the inits again.






            share|improve this answer








            New contributor




            leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.


















            • makes me wonder that maybe there should be revinits in the library somewhere...
              – Will Ness
              12 hours ago












            • Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
              – leftaroundabout
              12 hours ago










            • I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
              – Will Ness
              12 hours ago












            • Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
              – leftaroundabout
              11 hours ago






            • 1




              see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
              – Will Ness
              11 hours ago











            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            Paul is a new contributor. Be nice, and check out our Code of Conduct.










             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207619%2fgiven-a-haskell-list-return-all-sub-lists-obtained-by-removing-one-element%23new-answer', 'question_page');
            }
            );

            Post as a guest
































            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            13
            down vote



            accepted










            Here's a simpler way to implement it:



            subOneLists :: [a] -> [[a]]
            subOneLists =
            subOneLists (x:xs) = xs : map (x :) (subOneLists xs)





            share|improve this answer





















            • This is really clever
              – Paul
              21 hours ago






            • 3




              this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
              – Will Ness
              12 hours ago

















            up vote
            13
            down vote



            accepted










            Here's a simpler way to implement it:



            subOneLists :: [a] -> [[a]]
            subOneLists =
            subOneLists (x:xs) = xs : map (x :) (subOneLists xs)





            share|improve this answer





















            • This is really clever
              – Paul
              21 hours ago






            • 3




              this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
              – Will Ness
              12 hours ago















            up vote
            13
            down vote



            accepted







            up vote
            13
            down vote



            accepted






            Here's a simpler way to implement it:



            subOneLists :: [a] -> [[a]]
            subOneLists =
            subOneLists (x:xs) = xs : map (x :) (subOneLists xs)





            share|improve this answer












            Here's a simpler way to implement it:



            subOneLists :: [a] -> [[a]]
            subOneLists =
            subOneLists (x:xs) = xs : map (x :) (subOneLists xs)






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 22 hours ago









            4castle

            365212




            365212












            • This is really clever
              – Paul
              21 hours ago






            • 3




              this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
              – Will Ness
              12 hours ago




















            • This is really clever
              – Paul
              21 hours ago






            • 3




              this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
              – Will Ness
              12 hours ago


















            This is really clever
            – Paul
            21 hours ago




            This is really clever
            – Paul
            21 hours ago




            3




            3




            this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
            – Will Ness
            12 hours ago






            this repeats the old inits bug which makes (last $ subOneLists xs !! n) quadratic in n. My version as well as the newer, corrected version of inits in the library makes it linear.
            – Will Ness
            12 hours ago














            up vote
            5
            down vote













            List as an abstract concept can have many representations.



            In particular, with a list being represented by its "zipper" - a pairing of a reversed prefix and a suffix, it becomes possible to have a linear solution to this problem, as opposed to the quadratic one which is unavoidable with the plain linear representation :



            picks :: [a] -> [([a], [a])]
            picks =
            picks (x:xs) = go [x] xs
            where
            go pref suff@(x:xs) = (pref,suff) : go (x:pref) xs
            go pref = [(pref,)]


            Using this, your problem becomes



            foo = map ((a,b) -> revappend (tail a) b) . picks

            revappend a b = foldl (flip (:)) b a


            This is of course again quadratic, but maybe you could keep the prefixes reversed, to stay linear:



            import Control.Arrow (first)

            foo' = map (first tail) . picks -- or,
            -- = map ((x,y) -> (tail x, y)) . picks





            share|improve this answer



























              up vote
              5
              down vote













              List as an abstract concept can have many representations.



              In particular, with a list being represented by its "zipper" - a pairing of a reversed prefix and a suffix, it becomes possible to have a linear solution to this problem, as opposed to the quadratic one which is unavoidable with the plain linear representation :



              picks :: [a] -> [([a], [a])]
              picks =
              picks (x:xs) = go [x] xs
              where
              go pref suff@(x:xs) = (pref,suff) : go (x:pref) xs
              go pref = [(pref,)]


              Using this, your problem becomes



              foo = map ((a,b) -> revappend (tail a) b) . picks

              revappend a b = foldl (flip (:)) b a


              This is of course again quadratic, but maybe you could keep the prefixes reversed, to stay linear:



              import Control.Arrow (first)

              foo' = map (first tail) . picks -- or,
              -- = map ((x,y) -> (tail x, y)) . picks





              share|improve this answer

























                up vote
                5
                down vote










                up vote
                5
                down vote









                List as an abstract concept can have many representations.



                In particular, with a list being represented by its "zipper" - a pairing of a reversed prefix and a suffix, it becomes possible to have a linear solution to this problem, as opposed to the quadratic one which is unavoidable with the plain linear representation :



                picks :: [a] -> [([a], [a])]
                picks =
                picks (x:xs) = go [x] xs
                where
                go pref suff@(x:xs) = (pref,suff) : go (x:pref) xs
                go pref = [(pref,)]


                Using this, your problem becomes



                foo = map ((a,b) -> revappend (tail a) b) . picks

                revappend a b = foldl (flip (:)) b a


                This is of course again quadratic, but maybe you could keep the prefixes reversed, to stay linear:



                import Control.Arrow (first)

                foo' = map (first tail) . picks -- or,
                -- = map ((x,y) -> (tail x, y)) . picks





                share|improve this answer














                List as an abstract concept can have many representations.



                In particular, with a list being represented by its "zipper" - a pairing of a reversed prefix and a suffix, it becomes possible to have a linear solution to this problem, as opposed to the quadratic one which is unavoidable with the plain linear representation :



                picks :: [a] -> [([a], [a])]
                picks =
                picks (x:xs) = go [x] xs
                where
                go pref suff@(x:xs) = (pref,suff) : go (x:pref) xs
                go pref = [(pref,)]


                Using this, your problem becomes



                foo = map ((a,b) -> revappend (tail a) b) . picks

                revappend a b = foldl (flip (:)) b a


                This is of course again quadratic, but maybe you could keep the prefixes reversed, to stay linear:



                import Control.Arrow (first)

                foo' = map (first tail) . picks -- or,
                -- = map ((x,y) -> (tail x, y)) . picks






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 5 hours ago

























                answered 15 hours ago









                Will Ness

                7271620




                7271620






















                    up vote
                    3
                    down vote













                    Look out for standard functions that can help you!



                    Prelude Data.List> let subOneLists ls = zipWith (++) (inits ls) (tail $ tails ls)
                    Prelude Data.List> subOneLists [1, 2, 3, 4]
                    [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]


                    This uses the fact that the inits- and tails-elements at corresponding index always recombine to the original list, but with a variably splitting point:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tails ls))
                    (,[0,1,2,3,4,5,6,7])
                    ([0],[1,2,3,4,5,6,7])
                    ([0,1],[2,3,4,5,6,7])
                    ([0,1,2],[3,4,5,6,7])
                    ([0,1,2,3],[4,5,6,7])
                    ([0,1,2,3,4],[5,6,7])
                    ([0,1,2,3,4,5],[6,7])
                    ([0,1,2,3,4,5,6],[7])
                    ([0,1,2,3,4,5,6,7],)


                    If you now “shift up” that tails, by dropping its head, you effectively lose the head of each of the contained lists:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tail $ tails ls))
                    (,[1,2,3,4,5,6,7])
                    ([0],[2,3,4,5,6,7])
                    ([0,1],[3,4,5,6,7])
                    ([0,1,2],[4,5,6,7])
                    ([0,1,2,3],[5,6,7])
                    ([0,1,2,3,4],[6,7])
                    ([0,1,2,3,4,5],[7])
                    ([0,1,2,3,4,5,6],)


                    And that can just be ++ combined with the inits again.






                    share|improve this answer








                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.


















                    • makes me wonder that maybe there should be revinits in the library somewhere...
                      – Will Ness
                      12 hours ago












                    • Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      – leftaroundabout
                      12 hours ago










                    • I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      – Will Ness
                      12 hours ago












                    • Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                      – leftaroundabout
                      11 hours ago






                    • 1




                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      – Will Ness
                      11 hours ago















                    up vote
                    3
                    down vote













                    Look out for standard functions that can help you!



                    Prelude Data.List> let subOneLists ls = zipWith (++) (inits ls) (tail $ tails ls)
                    Prelude Data.List> subOneLists [1, 2, 3, 4]
                    [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]


                    This uses the fact that the inits- and tails-elements at corresponding index always recombine to the original list, but with a variably splitting point:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tails ls))
                    (,[0,1,2,3,4,5,6,7])
                    ([0],[1,2,3,4,5,6,7])
                    ([0,1],[2,3,4,5,6,7])
                    ([0,1,2],[3,4,5,6,7])
                    ([0,1,2,3],[4,5,6,7])
                    ([0,1,2,3,4],[5,6,7])
                    ([0,1,2,3,4,5],[6,7])
                    ([0,1,2,3,4,5,6],[7])
                    ([0,1,2,3,4,5,6,7],)


                    If you now “shift up” that tails, by dropping its head, you effectively lose the head of each of the contained lists:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tail $ tails ls))
                    (,[1,2,3,4,5,6,7])
                    ([0],[2,3,4,5,6,7])
                    ([0,1],[3,4,5,6,7])
                    ([0,1,2],[4,5,6,7])
                    ([0,1,2,3],[5,6,7])
                    ([0,1,2,3,4],[6,7])
                    ([0,1,2,3,4,5],[7])
                    ([0,1,2,3,4,5,6],)


                    And that can just be ++ combined with the inits again.






                    share|improve this answer








                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.


















                    • makes me wonder that maybe there should be revinits in the library somewhere...
                      – Will Ness
                      12 hours ago












                    • Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      – leftaroundabout
                      12 hours ago










                    • I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      – Will Ness
                      12 hours ago












                    • Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                      – leftaroundabout
                      11 hours ago






                    • 1




                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      – Will Ness
                      11 hours ago













                    up vote
                    3
                    down vote










                    up vote
                    3
                    down vote









                    Look out for standard functions that can help you!



                    Prelude Data.List> let subOneLists ls = zipWith (++) (inits ls) (tail $ tails ls)
                    Prelude Data.List> subOneLists [1, 2, 3, 4]
                    [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]


                    This uses the fact that the inits- and tails-elements at corresponding index always recombine to the original list, but with a variably splitting point:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tails ls))
                    (,[0,1,2,3,4,5,6,7])
                    ([0],[1,2,3,4,5,6,7])
                    ([0,1],[2,3,4,5,6,7])
                    ([0,1,2],[3,4,5,6,7])
                    ([0,1,2,3],[4,5,6,7])
                    ([0,1,2,3,4],[5,6,7])
                    ([0,1,2,3,4,5],[6,7])
                    ([0,1,2,3,4,5,6],[7])
                    ([0,1,2,3,4,5,6,7],)


                    If you now “shift up” that tails, by dropping its head, you effectively lose the head of each of the contained lists:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tail $ tails ls))
                    (,[1,2,3,4,5,6,7])
                    ([0],[2,3,4,5,6,7])
                    ([0,1],[3,4,5,6,7])
                    ([0,1,2],[4,5,6,7])
                    ([0,1,2,3],[5,6,7])
                    ([0,1,2,3,4],[6,7])
                    ([0,1,2,3,4,5],[7])
                    ([0,1,2,3,4,5,6],)


                    And that can just be ++ combined with the inits again.






                    share|improve this answer








                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    Look out for standard functions that can help you!



                    Prelude Data.List> let subOneLists ls = zipWith (++) (inits ls) (tail $ tails ls)
                    Prelude Data.List> subOneLists [1, 2, 3, 4]
                    [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]


                    This uses the fact that the inits- and tails-elements at corresponding index always recombine to the original list, but with a variably splitting point:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tails ls))
                    (,[0,1,2,3,4,5,6,7])
                    ([0],[1,2,3,4,5,6,7])
                    ([0,1],[2,3,4,5,6,7])
                    ([0,1,2],[3,4,5,6,7])
                    ([0,1,2,3],[4,5,6,7])
                    ([0,1,2,3,4],[5,6,7])
                    ([0,1,2,3,4,5],[6,7])
                    ([0,1,2,3,4,5,6],[7])
                    ([0,1,2,3,4,5,6,7],)


                    If you now “shift up” that tails, by dropping its head, you effectively lose the head of each of the contained lists:



                    Prelude Data.List> let ls = [0..7] in mapM_ print (zip (inits ls) (tail $ tails ls))
                    (,[1,2,3,4,5,6,7])
                    ([0],[2,3,4,5,6,7])
                    ([0,1],[3,4,5,6,7])
                    ([0,1,2],[4,5,6,7])
                    ([0,1,2,3],[5,6,7])
                    ([0,1,2,3,4],[6,7])
                    ([0,1,2,3,4,5],[7])
                    ([0,1,2,3,4,5,6],)


                    And that can just be ++ combined with the inits again.







                    share|improve this answer








                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    share|improve this answer



                    share|improve this answer






                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    answered 14 hours ago









                    leftaroundabout

                    1313




                    1313




                    New contributor




                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.





                    New contributor





                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.






                    leftaroundabout is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.












                    • makes me wonder that maybe there should be revinits in the library somewhere...
                      – Will Ness
                      12 hours ago












                    • Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      – leftaroundabout
                      12 hours ago










                    • I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      – Will Ness
                      12 hours ago












                    • Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                      – leftaroundabout
                      11 hours ago






                    • 1




                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      – Will Ness
                      11 hours ago


















                    • makes me wonder that maybe there should be revinits in the library somewhere...
                      – Will Ness
                      12 hours ago












                    • Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      – leftaroundabout
                      12 hours ago










                    • I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      – Will Ness
                      12 hours ago












                    • Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                      – leftaroundabout
                      11 hours ago






                    • 1




                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      – Will Ness
                      11 hours ago
















                    makes me wonder that maybe there should be revinits in the library somewhere...
                    – Will Ness
                    12 hours ago






                    makes me wonder that maybe there should be revinits in the library somewhere...
                    – Will Ness
                    12 hours ago














                    Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                    – leftaroundabout
                    12 hours ago




                    Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                    – leftaroundabout
                    12 hours ago












                    I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                    – Will Ness
                    12 hours ago






                    I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                    – Will Ness
                    12 hours ago














                    Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                    – leftaroundabout
                    11 hours ago




                    Ok, reverse . tails . reverse... yeah, that's ah bit meh. Still – I don't think it's good to pack base with every combination of reversal and disassembly. If you use any of these, then it's probably not optimal for performance anyway (compared to something Data.Vector based), and if performance isn't that critical then just combine simple list functions.
                    – leftaroundabout
                    11 hours ago




                    1




                    1




                    see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                    – Will Ness
                    11 hours ago




                    see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                    – Will Ness
                    11 hours ago










                    Paul is a new contributor. Be nice, and check out our Code of Conduct.










                     

                    draft saved


                    draft discarded


















                    Paul is a new contributor. Be nice, and check out our Code of Conduct.













                    Paul is a new contributor. Be nice, and check out our Code of Conduct.












                    Paul is a new contributor. Be nice, and check out our Code of Conduct.















                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207619%2fgiven-a-haskell-list-return-all-sub-lists-obtained-by-removing-one-element%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest




















































































                    Popular posts from this blog

                    Plaza Victoria

                    In PowerPoint, is there a keyboard shortcut for bulleted / numbered list?

                    How to put 3 figures in Latex with 2 figures side by side and 1 below these side by side images but in...