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










9












$begingroup$


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











$endgroup$
















    9












    $begingroup$


    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











    $endgroup$














      9












      9








      9


      2



      $begingroup$


      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











      $endgroup$




      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















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 5:40









      200_success

      129k15153415




      129k15153415










      asked Nov 14 '18 at 3:24









      PaulPaul

      1485




      1485




















          3 Answers
          3






          active

          oldest

          votes


















          13












          $begingroup$

          Here's a simpler way to implement it:



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





          share|improve this answer









          $endgroup$












          • $begingroup$
            This is really clever
            $endgroup$
            – Paul
            Nov 14 '18 at 4:10






          • 3




            $begingroup$
            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.
            $endgroup$
            – Will Ness
            Nov 14 '18 at 13:43



















          6












          $begingroup$

          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











          $endgroup$




















            5












            $begingroup$

            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









            $endgroup$












            • $begingroup$
              makes me wonder that maybe there should be revinits in the library somewhere...
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:28











            • $begingroup$
              Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
              $endgroup$
              – leftaroundabout
              Nov 14 '18 at 13:44










            • $begingroup$
              I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:46











            • $begingroup$
              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.
              $endgroup$
              – leftaroundabout
              Nov 14 '18 at 13:51






            • 1




              $begingroup$
              see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:52










            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',
            autoActivateHeartbeat: false,
            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
            );



            );













            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















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            13












            $begingroup$

            Here's a simpler way to implement it:



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





            share|improve this answer









            $endgroup$












            • $begingroup$
              This is really clever
              $endgroup$
              – Paul
              Nov 14 '18 at 4:10






            • 3




              $begingroup$
              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.
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:43
















            13












            $begingroup$

            Here's a simpler way to implement it:



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





            share|improve this answer









            $endgroup$












            • $begingroup$
              This is really clever
              $endgroup$
              – Paul
              Nov 14 '18 at 4:10






            • 3




              $begingroup$
              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.
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:43














            13












            13








            13





            $begingroup$

            Here's a simpler way to implement it:



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





            share|improve this answer









            $endgroup$



            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 Nov 14 '18 at 3:38









            4castle4castle

            390212




            390212











            • $begingroup$
              This is really clever
              $endgroup$
              – Paul
              Nov 14 '18 at 4:10






            • 3




              $begingroup$
              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.
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:43

















            • $begingroup$
              This is really clever
              $endgroup$
              – Paul
              Nov 14 '18 at 4:10






            • 3




              $begingroup$
              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.
              $endgroup$
              – Will Ness
              Nov 14 '18 at 13:43
















            $begingroup$
            This is really clever
            $endgroup$
            – Paul
            Nov 14 '18 at 4:10




            $begingroup$
            This is really clever
            $endgroup$
            – Paul
            Nov 14 '18 at 4:10




            3




            3




            $begingroup$
            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.
            $endgroup$
            – Will Ness
            Nov 14 '18 at 13:43





            $begingroup$
            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.
            $endgroup$
            – Will Ness
            Nov 14 '18 at 13:43














            6












            $begingroup$

            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











            $endgroup$

















              6












              $begingroup$

              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











              $endgroup$















                6












                6








                6





                $begingroup$

                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











                $endgroup$



                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 Nov 14 '18 at 20:45

























                answered Nov 14 '18 at 10:19









                Will NessWill Ness

                7371620




                7371620





















                    5












                    $begingroup$

                    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









                    $endgroup$












                    • $begingroup$
                      makes me wonder that maybe there should be revinits in the library somewhere...
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:28











                    • $begingroup$
                      Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:44










                    • $begingroup$
                      I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:46











                    • $begingroup$
                      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.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:51






                    • 1




                      $begingroup$
                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:52















                    5












                    $begingroup$

                    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









                    $endgroup$












                    • $begingroup$
                      makes me wonder that maybe there should be revinits in the library somewhere...
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:28











                    • $begingroup$
                      Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:44










                    • $begingroup$
                      I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:46











                    • $begingroup$
                      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.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:51






                    • 1




                      $begingroup$
                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:52













                    5












                    5








                    5





                    $begingroup$

                    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









                    $endgroup$



                    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












                    share|improve this answer



                    share|improve this answer










                    answered Nov 14 '18 at 11:18









                    leftaroundaboutleftaroundabout

                    1513




                    1513











                    • $begingroup$
                      makes me wonder that maybe there should be revinits in the library somewhere...
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:28











                    • $begingroup$
                      Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:44










                    • $begingroup$
                      I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:46











                    • $begingroup$
                      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.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:51






                    • 1




                      $begingroup$
                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:52
















                    • $begingroup$
                      makes me wonder that maybe there should be revinits in the library somewhere...
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:28











                    • $begingroup$
                      Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:44










                    • $begingroup$
                      I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:46











                    • $begingroup$
                      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.
                      $endgroup$
                      – leftaroundabout
                      Nov 14 '18 at 13:51






                    • 1




                      $begingroup$
                      see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                      $endgroup$
                      – Will Ness
                      Nov 14 '18 at 13:52















                    $begingroup$
                    makes me wonder that maybe there should be revinits in the library somewhere...
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:28





                    $begingroup$
                    makes me wonder that maybe there should be revinits in the library somewhere...
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:28













                    $begingroup$
                    Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                    $endgroup$
                    – leftaroundabout
                    Nov 14 '18 at 13:44




                    $begingroup$
                    Would probably make more sense to make that a rewrite rule for tails . reverse, if even necessary.
                    $endgroup$
                    – leftaroundabout
                    Nov 14 '18 at 13:44












                    $begingroup$
                    I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:46





                    $begingroup$
                    I meant reversed_inits [1..] !! 10 == [10,9..1]. :) (i.e. map reverse . inits but linear)
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:46













                    $begingroup$
                    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.
                    $endgroup$
                    – leftaroundabout
                    Nov 14 '18 at 13:51




                    $begingroup$
                    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.
                    $endgroup$
                    – leftaroundabout
                    Nov 14 '18 at 13:51




                    1




                    1




                    $begingroup$
                    see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:52




                    $begingroup$
                    see my updated comment. It's supposed to be linear, that's the point. and work for infinite inputs too.
                    $endgroup$
                    – Will Ness
                    Nov 14 '18 at 13:52

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    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















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3

                    Museum of Modern and Contemporary Art of Trento and Rovereto