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
"---"
我已经尝试了以下建议:How do I force evaluation of an IO action within `unsafePerformIO`?(BangPatterns实用注解+ $!
),并添加了Strict
和StrictData
实用注解,但是我仍然得到了行为不一致。
{-# 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的评估?
答案 0 :(得分:1)
Debug.Trace
函数会打印到stderr
,因此可以预期会发生交织。
至少,您可以将x
和它前面的字符串放在一起,以区别于其他print
输出。
ff :: Int -> Int
ff x = trace ("x is: " ++ show x) x
您还可以使用unsafePerformIO
重新定义打印到stdout
的跟踪功能,以强制执行某些排序。
答案 1 :(得分:1)
听起来您正在处理缓冲问题。您可以使用hFlush
或仅设置缓冲:
hSetBuffering stderr NoBuffering
hSetBuffering stdout NoBuffering
答案 2 :(得分:1)
myTrace :: Show a => a -> a
myTrace x = unsafePerformIO $ do
print x
pure x
以上似乎效果很好。感谢https://stackoverflow.com/users/6863749/li-yao-xia