
Roman | Alas, this doesn't work for Data.Vector.Storable. Here, we have to use peek | which gives us this: | | foo v x = ... foo v (Just (case readIntOffAddr# p# i# realWorld# of { (# s#, | n# #) -> | case touch# fp s# of { _ -> I# n# }})) ... | | SpecConstr eliminates the Just but can't unbox the Int. But it should be able to unbox that Int. It's not dissimilar to the situation when we have a rule f (g x) ---> e and we find an expression f (let w = rhs in g w) The rule-matcher automatically floats the let, so that it behaves just as if you'd written let w = rhs in f (g w) So the rule fires. In this case you have an ok-for-speculation primop instead of a let, but that should not get in the way. In your example, it should jolly well behave as if you had written | foo v x = ... case readIntOffAddr# p# i# realWorld# of { (# s#, n# #) -> | case touch# fp s# of { _ -> foo v (Just (I# n# }})) ... I'll implement that fix. It should catch cases like this where the primops involves are - ok-for-speculation - have just one result (ie only one case alternative Can you send me a small test case that will show the difference? Simon