Почему в файле *.prof так много обратных косых черт (\)?

Заглядывая в файл *.prof, сгенерированный с помощью +RTS -p с компиляцией с профилированием, я вижу много этих подпрограмм, названных \:

COST CENTRE           MODULE                         %time %alloc

main.\.\.\            Main                            74.1   85.8
unstreamChunks/inner  Data.Text.Internal.Lazy.Fusion  11.9    8.6 
inverseLetters.\      Main                             4.5    1.7 
main.\.\.\.(...)      Main                             2.9    1.0 
main.\.\.\.(...)      Main                             2.8    1.0 
unstreamChunks/resize Data.Text.Internal.Lazy.Fusion   1.2    0.8 
unstreamChunks/outer  Data.Text.Internal.Lazy.Fusion   1.1    0.5 

который выглядит загадочно для меня. Что они представляют?

Ответы

Ответ 1

Пусть

import Control.Monad

main = do
    forM_ [1..1000] $ \i ->
        if mod i 2 == 0 then putStrLn "Foo"
                        else print i

и запустите

ghc -rtsopts -prof -fprof-auto z.hs && ./z +RTS -p && cat z.prof

затем, следуя правила для установки МВЗ

COST CENTRE MODULE           %time %alloc
main.\      Main              80.0   84.4
main        Main              20.0   13.2
CAF         GHC.IO.Handle.FD   0.0    2.1

обратная косая черта показывает, что уровень стека, вы можете задать имена для каждого

forM_ [1..1000] $ \i ->
    {-# SCC "myBranch" #-}
    if mod i 2 == 0 then putStrLn "Foo"
                    else print i

и теперь

COST CENTRE MODULE           %time %alloc
myBranch    Main              90.0   84.4
main        Main              10.0   13.2
CAF         GHC.IO.Handle.FD   0.0    2.1

(Добавлен комментарий @trVoldemort)

Кроме того, (...), по-видимому, используется для let назначений с участием вычислений

data T = T Int (IO ()) (IO ())
main =
   forM_ [T (mod i 2) (putStrLn "Foo") (print i) | i <- [1..1000]] $ \q ->
        let T a b c = q -- Will be `(...)`
        in  if a == 0 then b else c

с выходом профиля

main.\        Main
 main.\.b     Main
 main.\.c     Main
 main.\.(...) Main
 main.\.a     Main

с помощью SCC pragma

forM_ [T (mod i 2) (putStrLn "Foo") (print i) | i <- [1..1000]] $ \q ->
     let T a b c = {-# SCC "myBind" #-} q
     in  if a == 0 then b else c

и вывод

main.\.b     Main
main.\.c     Main
main.\.(...) Main
 myBind      Main
main.\.a     Main