Get the first elements of a list of tuples












1















I have this list of tuples



[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]


I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"



I came up with this code, but it only gives me the replicate of the first tuple.



replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"


I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.










share|improve this question


















  • 1





    It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

    – leftaroundabout
    Nov 16 '18 at 0:38






  • 2





    f = (>>= uncurry replicate) is the fancy-pants approach.

    – amalloy
    Nov 16 '18 at 1:05






  • 1





    Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

    – fp_mora
    Nov 16 '18 at 2:20













  • map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

    – Manoj R
    Nov 16 '18 at 5:44
















1















I have this list of tuples



[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]


I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"



I came up with this code, but it only gives me the replicate of the first tuple.



replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"


I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.










share|improve this question


















  • 1





    It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

    – leftaroundabout
    Nov 16 '18 at 0:38






  • 2





    f = (>>= uncurry replicate) is the fancy-pants approach.

    – amalloy
    Nov 16 '18 at 1:05






  • 1





    Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

    – fp_mora
    Nov 16 '18 at 2:20













  • map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

    – Manoj R
    Nov 16 '18 at 5:44














1












1








1








I have this list of tuples



[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]


I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"



I came up with this code, but it only gives me the replicate of the first tuple.



replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"


I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.










share|improve this question














I have this list of tuples



[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]


I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"



I came up with this code, but it only gives me the replicate of the first tuple.



replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"


I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.







list haskell tuples replicate






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 16 '18 at 0:29









Tyler JoeTyler Joe

646




646








  • 1





    It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

    – leftaroundabout
    Nov 16 '18 at 0:38






  • 2





    f = (>>= uncurry replicate) is the fancy-pants approach.

    – amalloy
    Nov 16 '18 at 1:05






  • 1





    Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

    – fp_mora
    Nov 16 '18 at 2:20













  • map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

    – Manoj R
    Nov 16 '18 at 5:44














  • 1





    It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

    – leftaroundabout
    Nov 16 '18 at 0:38






  • 2





    f = (>>= uncurry replicate) is the fancy-pants approach.

    – amalloy
    Nov 16 '18 at 1:05






  • 1





    Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

    – fp_mora
    Nov 16 '18 at 2:20













  • map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

    – Manoj R
    Nov 16 '18 at 5:44








1




1





It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

– leftaroundabout
Nov 16 '18 at 0:38





It's usually much clearer not to work with fst and snd (and definitely not with head or !!) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.

– leftaroundabout
Nov 16 '18 at 0:38




2




2





f = (>>= uncurry replicate) is the fancy-pants approach.

– amalloy
Nov 16 '18 at 1:05





f = (>>= uncurry replicate) is the fancy-pants approach.

– amalloy
Nov 16 '18 at 1:05




1




1





Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

– fp_mora
Nov 16 '18 at 2:20







Your list is ils in [s | (n,c) <- ils, s <- replicate n c] produces the output you require.

– fp_mora
Nov 16 '18 at 2:20















map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

– Manoj R
Nov 16 '18 at 5:44





map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.

– Manoj R
Nov 16 '18 at 5:44












3 Answers
3






active

oldest

votes


















5














Since you already know how to find the correct answer for a single element, all you need is a little recursion



func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)


Mapping the values should also work. You just need to concatenate the resulting strings into one.



func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem


Or, if you are familiar with currying:



func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs


Finally, if you are comfortable using function composition, the definition becomes:



func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)


Using concat and map is so common, there is a function to do just that. It's concatMap.



func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)





share|improve this answer































    1














    You are correct about trying to use map. But first lets see why your code did not work



    replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))


    Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.



    Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.



    generate  =     
    generate (x:xs) = replicate (fst x) (snd x) ++ generate xs


    Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.



    generate  = 
    generate ((x,y):xs) = replicate x y ++ generate xs


    Now coming to map, so map will apply your function to every element of the list, here's the first try



    generate (x,y) = replicate x y
    map generate xs


    The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.



    Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).



    --first parameter is the function to apply, second is the accumulator, third is your list
    foldr step xs
    where step (x,y) acc =
    (replicate x y) ++ acc


    Again here I have used pattern matching in the function step to extract the elements of the tuple out.






    share|improve this answer































      1














      Let



      ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 


      in



      concat [replicate i x | (i, x) <- ls]


      will give



      "aaaabccaadeeee"


      The point-free version



      concat . map (uncurry replicate) 





      share|improve this answer

























        Your Answer






        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: "1"
        };
        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: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        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%2fstackoverflow.com%2fquestions%2f53329755%2fget-the-first-elements-of-a-list-of-tuples%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









        5














        Since you already know how to find the correct answer for a single element, all you need is a little recursion



        func :: [(Int, a)] -> [a]
        func =
        func ((n, elem):rest) = (replicate n elem) ++ (func rest)


        Mapping the values should also work. You just need to concatenate the resulting strings into one.



        func :: [(Int, a)] -> [a]
        func xs = concat $ map func2 xs where
        func2 (n, elem) = replicate n elem


        Or, if you are familiar with currying:



        func :: [(Int, a)] -> [a]
        func xs = concat $ map (uncurry replicate) xs


        Finally, if you are comfortable using function composition, the definition becomes:



        func :: [(Int, a)] -> [a]
        func = concat . map (uncurry replicate)


        Using concat and map is so common, there is a function to do just that. It's concatMap.



        func :: [(Int, a)] -> [a]
        func = concatMap (uncurry replicate)





        share|improve this answer




























          5














          Since you already know how to find the correct answer for a single element, all you need is a little recursion



          func :: [(Int, a)] -> [a]
          func =
          func ((n, elem):rest) = (replicate n elem) ++ (func rest)


          Mapping the values should also work. You just need to concatenate the resulting strings into one.



          func :: [(Int, a)] -> [a]
          func xs = concat $ map func2 xs where
          func2 (n, elem) = replicate n elem


          Or, if you are familiar with currying:



          func :: [(Int, a)] -> [a]
          func xs = concat $ map (uncurry replicate) xs


          Finally, if you are comfortable using function composition, the definition becomes:



          func :: [(Int, a)] -> [a]
          func = concat . map (uncurry replicate)


          Using concat and map is so common, there is a function to do just that. It's concatMap.



          func :: [(Int, a)] -> [a]
          func = concatMap (uncurry replicate)





          share|improve this answer


























            5












            5








            5







            Since you already know how to find the correct answer for a single element, all you need is a little recursion



            func :: [(Int, a)] -> [a]
            func =
            func ((n, elem):rest) = (replicate n elem) ++ (func rest)


            Mapping the values should also work. You just need to concatenate the resulting strings into one.



            func :: [(Int, a)] -> [a]
            func xs = concat $ map func2 xs where
            func2 (n, elem) = replicate n elem


            Or, if you are familiar with currying:



            func :: [(Int, a)] -> [a]
            func xs = concat $ map (uncurry replicate) xs


            Finally, if you are comfortable using function composition, the definition becomes:



            func :: [(Int, a)] -> [a]
            func = concat . map (uncurry replicate)


            Using concat and map is so common, there is a function to do just that. It's concatMap.



            func :: [(Int, a)] -> [a]
            func = concatMap (uncurry replicate)





            share|improve this answer













            Since you already know how to find the correct answer for a single element, all you need is a little recursion



            func :: [(Int, a)] -> [a]
            func =
            func ((n, elem):rest) = (replicate n elem) ++ (func rest)


            Mapping the values should also work. You just need to concatenate the resulting strings into one.



            func :: [(Int, a)] -> [a]
            func xs = concat $ map func2 xs where
            func2 (n, elem) = replicate n elem


            Or, if you are familiar with currying:



            func :: [(Int, a)] -> [a]
            func xs = concat $ map (uncurry replicate) xs


            Finally, if you are comfortable using function composition, the definition becomes:



            func :: [(Int, a)] -> [a]
            func = concat . map (uncurry replicate)


            Using concat and map is so common, there is a function to do just that. It's concatMap.



            func :: [(Int, a)] -> [a]
            func = concatMap (uncurry replicate)






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 16 '18 at 1:15









            merlynmerlyn

            1,77011323




            1,77011323

























                1














                You are correct about trying to use map. But first lets see why your code did not work



                replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))


                Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.



                Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.



                generate  =     
                generate (x:xs) = replicate (fst x) (snd x) ++ generate xs


                Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.



                generate  = 
                generate ((x,y):xs) = replicate x y ++ generate xs


                Now coming to map, so map will apply your function to every element of the list, here's the first try



                generate (x,y) = replicate x y
                map generate xs


                The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.



                Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).



                --first parameter is the function to apply, second is the accumulator, third is your list
                foldr step xs
                where step (x,y) acc =
                (replicate x y) ++ acc


                Again here I have used pattern matching in the function step to extract the elements of the tuple out.






                share|improve this answer




























                  1














                  You are correct about trying to use map. But first lets see why your code did not work



                  replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))


                  Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.



                  Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.



                  generate  =     
                  generate (x:xs) = replicate (fst x) (snd x) ++ generate xs


                  Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.



                  generate  = 
                  generate ((x,y):xs) = replicate x y ++ generate xs


                  Now coming to map, so map will apply your function to every element of the list, here's the first try



                  generate (x,y) = replicate x y
                  map generate xs


                  The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.



                  Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).



                  --first parameter is the function to apply, second is the accumulator, third is your list
                  foldr step xs
                  where step (x,y) acc =
                  (replicate x y) ++ acc


                  Again here I have used pattern matching in the function step to extract the elements of the tuple out.






                  share|improve this answer


























                    1












                    1








                    1







                    You are correct about trying to use map. But first lets see why your code did not work



                    replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))


                    Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.



                    Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.



                    generate  =     
                    generate (x:xs) = replicate (fst x) (snd x) ++ generate xs


                    Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.



                    generate  = 
                    generate ((x,y):xs) = replicate x y ++ generate xs


                    Now coming to map, so map will apply your function to every element of the list, here's the first try



                    generate (x,y) = replicate x y
                    map generate xs


                    The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.



                    Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).



                    --first parameter is the function to apply, second is the accumulator, third is your list
                    foldr step xs
                    where step (x,y) acc =
                    (replicate x y) ++ acc


                    Again here I have used pattern matching in the function step to extract the elements of the tuple out.






                    share|improve this answer













                    You are correct about trying to use map. But first lets see why your code did not work



                    replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))


                    Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.



                    Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.



                    generate  =     
                    generate (x:xs) = replicate (fst x) (snd x) ++ generate xs


                    Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.



                    generate  = 
                    generate ((x,y):xs) = replicate x y ++ generate xs


                    Now coming to map, so map will apply your function to every element of the list, here's the first try



                    generate (x,y) = replicate x y
                    map generate xs


                    The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.



                    Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).



                    --first parameter is the function to apply, second is the accumulator, third is your list
                    foldr step xs
                    where step (x,y) acc =
                    (replicate x y) ++ acc


                    Again here I have used pattern matching in the function step to extract the elements of the tuple out.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 16 '18 at 1:16









                    peeyush singhpeeyush singh

                    536316




                    536316























                        1














                        Let



                        ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 


                        in



                        concat [replicate i x | (i, x) <- ls]


                        will give



                        "aaaabccaadeeee"


                        The point-free version



                        concat . map (uncurry replicate) 





                        share|improve this answer






























                          1














                          Let



                          ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 


                          in



                          concat [replicate i x | (i, x) <- ls]


                          will give



                          "aaaabccaadeeee"


                          The point-free version



                          concat . map (uncurry replicate) 





                          share|improve this answer




























                            1












                            1








                            1







                            Let



                            ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 


                            in



                            concat [replicate i x | (i, x) <- ls]


                            will give



                            "aaaabccaadeeee"


                            The point-free version



                            concat . map (uncurry replicate) 





                            share|improve this answer















                            Let



                            ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 


                            in



                            concat [replicate i x | (i, x) <- ls]


                            will give



                            "aaaabccaadeeee"


                            The point-free version



                            concat . map (uncurry replicate) 






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 16 '18 at 14:09

























                            answered Nov 16 '18 at 14:02









                            Elmex80sElmex80s

                            2,0471814




                            2,0471814






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • 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.


                                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%2fstackoverflow.com%2fquestions%2f53329755%2fget-the-first-elements-of-a-list-of-tuples%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







                                Popular posts from this blog

                                Bressuire

                                Vorschmack

                                Quarantine