Haskell - How to print some value in a function for debugging purpose?
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
add a comment |
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
add a comment |
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
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
haskell
asked Nov 23 '18 at 5:34
wind2412
384213
384213
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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)
add a comment |
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
add a comment |
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"
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 typeIO awith anyabecause>>ignores result of left argument.
– talex
Nov 23 '18 at 5:54
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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)
add a comment |
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)
add a comment |
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)
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)
answered Nov 23 '18 at 7:10
Jon Purdy
37.8k666125
37.8k666125
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
edited Nov 23 '18 at 6:10
answered Nov 23 '18 at 5:56
n.m.
71.2k882167
71.2k882167
add a comment |
add a comment |
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"
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 typeIO awith anyabecause>>ignores result of left argument.
– talex
Nov 23 '18 at 5:54
add a comment |
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"
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 typeIO awith anyabecause>>ignores result of left argument.
– talex
Nov 23 '18 at 5:54
add a comment |
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"
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"
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 typeIO awith anyabecause>>ignores result of left argument.
– talex
Nov 23 '18 at 5:54
add a comment |
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 typeIO awith anyabecause>>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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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