I've tried to come up with ways to break sharing of top level constants in haskell, but so far none of them worked:
module Main where
import Debug.Trace
x1 :: Int
x1 = trace "Eval1" $ 10 + 10
x2 :: () -> Int
x2 = \() -> trace "Eval2" $ 10 + 10
x3 :: () -> Int
x3 () = trace "Eval3" $ 10 + 10
x4 :: () -> Int
x4 () = v
where v = trace "Eval4" $ 10 + 10
x5 :: () -> Int
x5 = \() -> v
where v = trace "Eval5" $ 10 + 10
x6 :: () -> Int
x6 () = let v = trace "Eval6" $ 10 + 10 in v
x7 :: () -> Int
x7 = let v = trace "Eval7" $ 10 + 10 in \() -> v
x8 :: () -> Int
x8 = \() -> let v = trace "Eval8" $ 10 + 10 in v
f :: Int -> Int -> Int
f y z = y + z
main :: IO ()
main = do
putStrLn "Start"
print (f x1 3)
print (f x1 4)
print (f (x2 ()) 3)
print (f (x2 ()) 4)
print (f (x3 ()) 3)
print (f (x3 ()) 4)
print (f (x4 ()) 3)
print (f (x4 ()) 4)
print (f (x5 ()) 3)
print (f (x5 ()) 4)
print (f (x6 ()) 3)
print (f (x6 ()) 4)
print (f (x7 ()) 3)
print (f (x7 ()) 4)
print (f (x8 ()) 3)
print (f (x8 ()) 4)
I've found that it breaks the sharing when I put {-# INLINE#-}
pragmas on the definitions (then it works for all of them).
So my question is: Is there another way to break the sharing of a top level constant in haskell with GHC that doesn't involve INLINE
pragmas? Is it guarranted that putting INLINE
pragmas breaks the sharing, even for bigger definitions? If not, is there a guarranted way?
Why do I need this? For example, when I write a benchmark, I have a tree structure that is traversed. This structure should not be shared between runs of the benchmark, because building it is part of the benchmark.