example :: Int -> Float
example x = iter phi (unfold psi x)
where
psi :: Int -> Either Float (Int, Int)
psi n = if even n then Left 2.5 else Right (5, n)
phi :: (Int, Float) -> Float
phi (x', y') = fromIntegral x' * y'
With deforestation. Note the absence of tuples or Either.
Rec {
$wc :: Int# -> Float#
$wc
= \ (ww :: Int#) ->
case remInt# ww 2# of {
__DEFAULT ->
case $wc ww of ww1 { __DEFAULT -> timesFloat# 5.0# ww1 };
0# -> 2.5#
}
end Rec }
example_c :: Int -> Float
example_c
= \ (w :: Int) ->
case w of { I# ww1 -> case $wc ww1 of ww2 { __DEFAULT -> F# ww2 } }
example :: Int -> Float
example = example_c
Without deforestation:
example5 :: (Int, Float) -> Float
example5
= \ (ds :: (Int, Float)) ->
case ds of { (x, y) ->
case x of { I# i ->
case y of { F# y1 -> F# (timesFloat# (int2Float# i) y1) }
}
}
example4 :: Int
example4 = I# 5#
example3 :: Float
example3 = F# 2.5#
example2 :: Either Float (Int, Int)
example2 = Left example3
example1 :: Int -> Either Float (Int, Int)
example1
= \ (n :: Int) ->
case n of wild2 { I# x1 ->
case remInt# x1 2# of {
__DEFAULT -> Right (example4, wild2);
0# -> example2
}
}
example :: Int -> Float
example
= \ (x :: Int) ->
example_$siter example5 (example_$sunfold example1 x)
One thing to note is that for this to happen, you must use the new buildF function to build up your Free structures, and then ensure that your building function is inlined so GHC can see the occurrence of iter f (buildF g) to apply the rewrite rule.
Consider this example code:
With deforestation. Note the absence of tuples or Either.
Without deforestation:
One thing to note is that for this to happen, you must use the new
buildF
function to build up yourFree
structures, and then ensure that your building function is inlined so GHC can see the occurrence ofiter f (buildF g)
to apply the rewrite rule.