Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use deforestation to simplify Core related to iter #187

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jwiegley
Copy link
Collaborator

@jwiegley jwiegley commented Apr 5, 2019

Consider this example code:

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.

Note that for this to take effect, any functions that build up Free structures
must do so using buildF.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant