Haskell - How to print some value in a function for debugging purpose?












2














I'm a Haskell newbie and I want to do something which has a side effect like this:



i = 3.0

main :: IO ()
main = let m = print i in putStrLn "Hello world"


Then I can know the value of i when main runs, but the I didn't print. I add ! before m but it also doesn't work. I would like to know how to hack this, thanks in advance!










share|improve this question



























    2














    I'm a Haskell newbie and I want to do something which has a side effect like this:



    i = 3.0

    main :: IO ()
    main = let m = print i in putStrLn "Hello world"


    Then I can know the value of i when main runs, but the I didn't print. I add ! before m but it also doesn't work. I would like to know how to hack this, thanks in advance!










    share|improve this question

























      2












      2








      2


      1





      I'm a Haskell newbie and I want to do something which has a side effect like this:



      i = 3.0

      main :: IO ()
      main = let m = print i in putStrLn "Hello world"


      Then I can know the value of i when main runs, but the I didn't print. I add ! before m but it also doesn't work. I would like to know how to hack this, thanks in advance!










      share|improve this question













      I'm a Haskell newbie and I want to do something which has a side effect like this:



      i = 3.0

      main :: IO ()
      main = let m = print i in putStrLn "Hello world"


      Then I can know the value of i when main runs, but the I didn't print. I add ! before m but it also doesn't work. I would like to know how to hack this, thanks in advance!







      haskell






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 5:34









      wind2412

      384213




      384213
























          3 Answers
          3






          active

          oldest

          votes


















          3














          In an IO action, you can just use putStrLn or print as usual, like



          do
          print i
          putStrLn "Hello world"


          Which desugars to print i >> putStrLn "…". This is equivalent, but not really any better because the action m doesn’t really need to be named:



          let m = print i  -- define an action
          in do
          m -- ensure the action is actually executed
          putStrLn "Hello world"


          In a pure function, you can use trace or traceShow from Debug.Trace:



          traceShow i (putStrLn "Hello world")


          But be aware that these print when the expression is forced, which may be in a different order than you may expect due to lazy evaluation, or not at all if a value is never used. You can add strictness annotations with seq or BangPatterns as you tried for the monadic code to assist with making sure that things are forced when you expect—the reason !m = … didn’t work for your IO action is that the strictness annotation only makes the expression evaluated, producing an IO action but not executing it because it’s not sequenced with another action as part of main. Remember: you can only (purely) construct IO actions and bind them together; the runtime is what actually executes them.



          Finally, in a “pure” monad where you don’t have IO available, you can still use trace &c., for example in the list monad:



          numbers :: [Int]
          numbers = do
          x <- [1, 2, 3]
          traceShow x (pure ())
          y <- [4, 5, 6]
          traceShow y (pure ())
          pure (x * y)





          share|improve this answer





























            4














            For debugging, use trace and friends.



            import Debug.Trace
            i = 3.0

            main :: IO ()
            main = traceShow i $ putStrLn "Hello world"


            See it live



            Note the trace appears on the standard error stream, as debugging output should.



            The function you use trace in doesn't have to be IO-typed. This for example will also work:



            add a b = a + traceShow i b


            Trace functions are a bit foreign to Haskell because they are technically impure. However the side effects are limited in scope and not observable by the program itself, so it's kinda OK.



            More info






            share|improve this answer































              3














              You created m but never used it. To fix that you can try:



              i = 3.0

              main :: IO ()
              main = let m = print i in m >> putStrLn "Hello world"





              share|improve this answer





















              • Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                – wind2412
                Nov 23 '18 at 5:52






              • 2




                For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                – talex
                Nov 23 '18 at 5:54











              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%2f53441113%2fhaskell-how-to-print-some-value-in-a-function-for-debugging-purpose%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









              3














              In an IO action, you can just use putStrLn or print as usual, like



              do
              print i
              putStrLn "Hello world"


              Which desugars to print i >> putStrLn "…". This is equivalent, but not really any better because the action m doesn’t really need to be named:



              let m = print i  -- define an action
              in do
              m -- ensure the action is actually executed
              putStrLn "Hello world"


              In a pure function, you can use trace or traceShow from Debug.Trace:



              traceShow i (putStrLn "Hello world")


              But be aware that these print when the expression is forced, which may be in a different order than you may expect due to lazy evaluation, or not at all if a value is never used. You can add strictness annotations with seq or BangPatterns as you tried for the monadic code to assist with making sure that things are forced when you expect—the reason !m = … didn’t work for your IO action is that the strictness annotation only makes the expression evaluated, producing an IO action but not executing it because it’s not sequenced with another action as part of main. Remember: you can only (purely) construct IO actions and bind them together; the runtime is what actually executes them.



              Finally, in a “pure” monad where you don’t have IO available, you can still use trace &c., for example in the list monad:



              numbers :: [Int]
              numbers = do
              x <- [1, 2, 3]
              traceShow x (pure ())
              y <- [4, 5, 6]
              traceShow y (pure ())
              pure (x * y)





              share|improve this answer


























                3














                In an IO action, you can just use putStrLn or print as usual, like



                do
                print i
                putStrLn "Hello world"


                Which desugars to print i >> putStrLn "…". This is equivalent, but not really any better because the action m doesn’t really need to be named:



                let m = print i  -- define an action
                in do
                m -- ensure the action is actually executed
                putStrLn "Hello world"


                In a pure function, you can use trace or traceShow from Debug.Trace:



                traceShow i (putStrLn "Hello world")


                But be aware that these print when the expression is forced, which may be in a different order than you may expect due to lazy evaluation, or not at all if a value is never used. You can add strictness annotations with seq or BangPatterns as you tried for the monadic code to assist with making sure that things are forced when you expect—the reason !m = … didn’t work for your IO action is that the strictness annotation only makes the expression evaluated, producing an IO action but not executing it because it’s not sequenced with another action as part of main. Remember: you can only (purely) construct IO actions and bind them together; the runtime is what actually executes them.



                Finally, in a “pure” monad where you don’t have IO available, you can still use trace &c., for example in the list monad:



                numbers :: [Int]
                numbers = do
                x <- [1, 2, 3]
                traceShow x (pure ())
                y <- [4, 5, 6]
                traceShow y (pure ())
                pure (x * y)





                share|improve this answer
























                  3












                  3








                  3






                  In an IO action, you can just use putStrLn or print as usual, like



                  do
                  print i
                  putStrLn "Hello world"


                  Which desugars to print i >> putStrLn "…". This is equivalent, but not really any better because the action m doesn’t really need to be named:



                  let m = print i  -- define an action
                  in do
                  m -- ensure the action is actually executed
                  putStrLn "Hello world"


                  In a pure function, you can use trace or traceShow from Debug.Trace:



                  traceShow i (putStrLn "Hello world")


                  But be aware that these print when the expression is forced, which may be in a different order than you may expect due to lazy evaluation, or not at all if a value is never used. You can add strictness annotations with seq or BangPatterns as you tried for the monadic code to assist with making sure that things are forced when you expect—the reason !m = … didn’t work for your IO action is that the strictness annotation only makes the expression evaluated, producing an IO action but not executing it because it’s not sequenced with another action as part of main. Remember: you can only (purely) construct IO actions and bind them together; the runtime is what actually executes them.



                  Finally, in a “pure” monad where you don’t have IO available, you can still use trace &c., for example in the list monad:



                  numbers :: [Int]
                  numbers = do
                  x <- [1, 2, 3]
                  traceShow x (pure ())
                  y <- [4, 5, 6]
                  traceShow y (pure ())
                  pure (x * y)





                  share|improve this answer












                  In an IO action, you can just use putStrLn or print as usual, like



                  do
                  print i
                  putStrLn "Hello world"


                  Which desugars to print i >> putStrLn "…". This is equivalent, but not really any better because the action m doesn’t really need to be named:



                  let m = print i  -- define an action
                  in do
                  m -- ensure the action is actually executed
                  putStrLn "Hello world"


                  In a pure function, you can use trace or traceShow from Debug.Trace:



                  traceShow i (putStrLn "Hello world")


                  But be aware that these print when the expression is forced, which may be in a different order than you may expect due to lazy evaluation, or not at all if a value is never used. You can add strictness annotations with seq or BangPatterns as you tried for the monadic code to assist with making sure that things are forced when you expect—the reason !m = … didn’t work for your IO action is that the strictness annotation only makes the expression evaluated, producing an IO action but not executing it because it’s not sequenced with another action as part of main. Remember: you can only (purely) construct IO actions and bind them together; the runtime is what actually executes them.



                  Finally, in a “pure” monad where you don’t have IO available, you can still use trace &c., for example in the list monad:



                  numbers :: [Int]
                  numbers = do
                  x <- [1, 2, 3]
                  traceShow x (pure ())
                  y <- [4, 5, 6]
                  traceShow y (pure ())
                  pure (x * y)






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 23 '18 at 7:10









                  Jon Purdy

                  37.8k666125




                  37.8k666125

























                      4














                      For debugging, use trace and friends.



                      import Debug.Trace
                      i = 3.0

                      main :: IO ()
                      main = traceShow i $ putStrLn "Hello world"


                      See it live



                      Note the trace appears on the standard error stream, as debugging output should.



                      The function you use trace in doesn't have to be IO-typed. This for example will also work:



                      add a b = a + traceShow i b


                      Trace functions are a bit foreign to Haskell because they are technically impure. However the side effects are limited in scope and not observable by the program itself, so it's kinda OK.



                      More info






                      share|improve this answer




























                        4














                        For debugging, use trace and friends.



                        import Debug.Trace
                        i = 3.0

                        main :: IO ()
                        main = traceShow i $ putStrLn "Hello world"


                        See it live



                        Note the trace appears on the standard error stream, as debugging output should.



                        The function you use trace in doesn't have to be IO-typed. This for example will also work:



                        add a b = a + traceShow i b


                        Trace functions are a bit foreign to Haskell because they are technically impure. However the side effects are limited in scope and not observable by the program itself, so it's kinda OK.



                        More info






                        share|improve this answer


























                          4












                          4








                          4






                          For debugging, use trace and friends.



                          import Debug.Trace
                          i = 3.0

                          main :: IO ()
                          main = traceShow i $ putStrLn "Hello world"


                          See it live



                          Note the trace appears on the standard error stream, as debugging output should.



                          The function you use trace in doesn't have to be IO-typed. This for example will also work:



                          add a b = a + traceShow i b


                          Trace functions are a bit foreign to Haskell because they are technically impure. However the side effects are limited in scope and not observable by the program itself, so it's kinda OK.



                          More info






                          share|improve this answer














                          For debugging, use trace and friends.



                          import Debug.Trace
                          i = 3.0

                          main :: IO ()
                          main = traceShow i $ putStrLn "Hello world"


                          See it live



                          Note the trace appears on the standard error stream, as debugging output should.



                          The function you use trace in doesn't have to be IO-typed. This for example will also work:



                          add a b = a + traceShow i b


                          Trace functions are a bit foreign to Haskell because they are technically impure. However the side effects are limited in scope and not observable by the program itself, so it's kinda OK.



                          More info







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 23 '18 at 6:10

























                          answered Nov 23 '18 at 5:56









                          n.m.

                          71.2k882167




                          71.2k882167























                              3














                              You created m but never used it. To fix that you can try:



                              i = 3.0

                              main :: IO ()
                              main = let m = print i in m >> putStrLn "Hello world"





                              share|improve this answer





















                              • Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                                – wind2412
                                Nov 23 '18 at 5:52






                              • 2




                                For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                                – talex
                                Nov 23 '18 at 5:54
















                              3














                              You created m but never used it. To fix that you can try:



                              i = 3.0

                              main :: IO ()
                              main = let m = print i in m >> putStrLn "Hello world"





                              share|improve this answer





















                              • Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                                – wind2412
                                Nov 23 '18 at 5:52






                              • 2




                                For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                                – talex
                                Nov 23 '18 at 5:54














                              3












                              3








                              3






                              You created m but never used it. To fix that you can try:



                              i = 3.0

                              main :: IO ()
                              main = let m = print i in m >> putStrLn "Hello world"





                              share|improve this answer












                              You created m but never used it. To fix that you can try:



                              i = 3.0

                              main :: IO ()
                              main = let m = print i in m >> putStrLn "Hello world"






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 23 '18 at 5:45









                              talex

                              9,9231546




                              9,9231546












                              • Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                                – wind2412
                                Nov 23 '18 at 5:52






                              • 2




                                For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                                – talex
                                Nov 23 '18 at 5:54


















                              • Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                                – wind2412
                                Nov 23 '18 at 5:52






                              • 2




                                For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                                – talex
                                Nov 23 '18 at 5:54
















                              Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                              – wind2412
                              Nov 23 '18 at 5:52




                              Is there a way to execute the side effect without using it? If the type in the left side of >> different from the right one, it will not work.
                              – wind2412
                              Nov 23 '18 at 5:52




                              2




                              2




                              For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                              – talex
                              Nov 23 '18 at 5:54




                              For the first question answer is "no". For the second: It should have type IO a with any a because >> ignores result of left argument.
                              – talex
                              Nov 23 '18 at 5:54


















                              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.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • 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%2f53441113%2fhaskell-how-to-print-some-value-in-a-function-for-debugging-purpose%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

                              Sphinx de Gizeh

                              Dijon

                              Guerrita