Как я могу заставить операторы трассировки отладки оценивать по порядку? - PullRequest
0 голосов
/ 01 декабря 2018
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
"---"

У меня естьпопробовал следующие предложения: Как принудительно оценить действие ввода-вывода в `unsafePerformIO`? (BangPatterns Pragma + $!), а также добавить прагмы 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 

Есть ли решение, не требующее знания о строгости/ Оценка Хаскелла?

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Похоже, вы имеете дело с проблемами буферизации.Вы можете использовать hFlush или просто установить буферизацию:

hSetBuffering stderr NoBuffering
hSetBuffering stdout NoBuffering
0 голосов
/ 02 декабря 2018
myTrace :: Show a => a -> a
myTrace x = unsafePerformIO $ do
  print x
  pure x

Выше, кажется, работает хорошо.Благодаря https://stackoverflow.com/users/6863749/li-yao-xia

0 голосов
/ 01 декабря 2018

Debug.Trace функции печатают в stderr, поэтому следует ожидать чередования.

По крайней мере, вы можете поместить x и строку перед ней вместе, чтобы отличить ее от других printoutput.

ff :: Int -> Int
ff x = trace ("x is: " ++ show x) x

Вы также можете использовать unsafePerformIO, чтобы переопределить функции трассировки, которые печатаются в stdout, чтобы обеспечить некоторое упорядочение.

...