如何强制调试跟踪语句按顺序求值?
How can I force debug trace statements to evaluate in order?
import Debug.Trace
main :: IO ()
main = do
let b = (fff 2 10)
print b
let c = (fff 3 10)
print c
print "---"
ff :: (->) Int Int
ff = do
x <- traceShow "x is: " . traceShowId
pure $ (x)
fff :: Int -> Int -> Int
fff = do
(-) . ff
跟踪函数似乎被延迟评估或意味着输出可能有所不同:
"x is: "
2
-8
"x is: "
-7
3
"---"
在另一个 运行:
"x is: "
2
"x is: "
3
-8
-7
"---"
我已经尝试了这里的建议: (BangPatterns Pragma + $!
) 以及添加 Strict
和 StrictData
pragma,但是我仍然得到不一致的行为。
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE StrictData #-}
import Debug.Trace
main :: IO ()
main = do
let !b = (fff 2 10)
print b
let !c = (fff 3 10)
print c
print "---"
ff :: (->) Int Int
ff = do
x <- id $! (traceShow "x is: " . traceShowId)
pure $ (x)
fff :: Int -> Int -> Int
fff = do
(-) . ff
我也试过使用 unsafePerformIo
但这有类似的行为:
hmm :: a -> a
hmm x = unsafePerformIO $! do
pure x
ff :: Int -> Int
ff z = do
hmm (trace "x is: " . traceShowId) $ z
是否有无需了解严格性/Haskell评估的解决方案?
Debug.Trace
函数打印到 stderr
,因此交错是可以预期的。
至少,您可以将 x
和它前面的字符串放在一起,以区别于其他 print
输出。
ff :: Int -> Int
ff x = trace ("x is: " ++ show x) x
您还可以使用 unsafePerformIO
重新定义打印到 stdout
的跟踪函数以强制执行某些顺序。
听起来您正在处理缓冲问题。您可以使用 hFlush
或只设置缓冲:
hSetBuffering stderr NoBuffering
hSetBuffering stdout NoBuffering
myTrace :: Show a => a -> a
myTrace x = unsafePerformIO $ do
print x
pure x
import Debug.Trace
main :: IO ()
main = do
let b = (fff 2 10)
print b
let c = (fff 3 10)
print c
print "---"
ff :: (->) Int Int
ff = do
x <- traceShow "x is: " . traceShowId
pure $ (x)
fff :: Int -> Int -> Int
fff = do
(-) . ff
跟踪函数似乎被延迟评估或意味着输出可能有所不同:
"x is: "
2
-8
"x is: "
-7
3
"---"
在另一个 运行:
"x is: "
2
"x is: "
3
-8
-7
"---"
我已经尝试了这里的建议:$!
) 以及添加 Strict
和 StrictData
pragma,但是我仍然得到不一致的行为。
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE StrictData #-}
import Debug.Trace
main :: IO ()
main = do
let !b = (fff 2 10)
print b
let !c = (fff 3 10)
print c
print "---"
ff :: (->) Int Int
ff = do
x <- id $! (traceShow "x is: " . traceShowId)
pure $ (x)
fff :: Int -> Int -> Int
fff = do
(-) . ff
我也试过使用 unsafePerformIo
但这有类似的行为:
hmm :: a -> a
hmm x = unsafePerformIO $! do
pure x
ff :: Int -> Int
ff z = do
hmm (trace "x is: " . traceShowId) $ z
是否有无需了解严格性/Haskell评估的解决方案?
Debug.Trace
函数打印到 stderr
,因此交错是可以预期的。
至少,您可以将 x
和它前面的字符串放在一起,以区别于其他 print
输出。
ff :: Int -> Int
ff x = trace ("x is: " ++ show x) x
您还可以使用 unsafePerformIO
重新定义打印到 stdout
的跟踪函数以强制执行某些顺序。
听起来您正在处理缓冲问题。您可以使用 hFlush
或只设置缓冲:
hSetBuffering stderr NoBuffering
hSetBuffering stdout NoBuffering
myTrace :: Show a => a -> a
myTrace x = unsafePerformIO $ do
print x
pure x