summaryrefslogtreecommitdiff
path: root/testsuite/tests/stranal/sigs/T18957.hs
blob: b49ed1a4b89edad8b3766f9be6192d4ce7eaf1b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{-# OPTIONS_GHC -O2 -fforce-recomp #-}
{-# LANGUAGE BangPatterns #-}

-- | This ticket is about the demand `seq` puts its first argument under and how
-- that affects call demands.
module T18957 where

-- | Should put its first argument under head demand
-- Note that seq' is like seq, but NOINLINE, so the calling code will not have
-- access to the case binder. That is the difference between 'h1' and 'h2'.
seq' :: a -> b -> b
seq' a b = seq a b
{-# NOINLINE seq' #-}

-- | The first argument is evaluated at once, but called every time it's
-- evaluated
g :: (Int -> Int) -> Int -> Int
g f x = if x < 100 then f x else 200

-- | The first argument is evaluated multiple times, but called at most once
-- every time it's evaluated
h1 :: (Int -> Int) -> Int -> Int
h1 f x = f `seq'` if x < 100 then f x else 200

-- | Like h1, but using `seq` directly, which will rewrite the call site
-- of @f@ to use the case binder instead, which means we won't evaluate it an
-- additional time. So evaluated once and called once.
h2 :: (Int -> Int) -> Int -> Int
h2 f x = f `seq` if x < 100 then f x else 200

-- | The first argument is evaluated lazily and multiple times, but called every
-- time it's evaluated.
h3 :: (Int -> Int) -> Int -> Int
h3 f x = if x < 100 then f x + f (x+1) else 200