Is there a way to optimize out some foreign calls?

H - I'm wondering if there is any way to specify that certain sequences of foreign calls can be merged into a single foreign call. For example, in a common situation where a state of a foreign API is pushed and popped so that the previous state is restored, I'd like successive pops to avoid wasting time restoring intermediate states as in: -- push a state onto the API's state stack (without changing the state) foreign import ccall api_push :: State -> IO () -- discards the state at the top of the stack foreign import ccall api_pop :: IO () -- synchronises the API's state with the state at the top of the stack foreign import ccall api_sync :: IO () use :: State -> IO () -> IO () use s action = do api_push s api_sync action api_pop api_sync -- put the API back into the previous state main = do use State1 $ do actionIn1a use State2 $ do actionIn2 use State3 $ do actionIn3 actionIn1b If 'use' is inlined, the compiler would (presumably) produce code like: main = do api_push State1 api_sync actionIn1a api_push State2 api_sync actionIn2 api_push State3 api_sync actionIn3 api_pop api_sync -- This is a waste of time api_pop api_sync actionIn1b api_pop api_sync I'm wondering if there is any way to cause the compiler to avoid the wasteful call to api_sync above. I'm thinking in terms of some way of marking foreign functions to specify how they can be optimized out or specifying rewrite sequences eg x >> api_sync >> api_pop >> api_sync >> y = x >> api_pop >> api_sync >> y I've read the manual (7.10) on rewrite rules, but I'm having difficulty understanding how to express the lhs of the above equation as a rewrite rule so that it matches a sequence anywhere in a do block (to deal with nested parentheses and the use of >>= instead of >>) Any ideas? Thanks, Brian.
participants (1)
-
Brian Hulley