RULES for SPECIALIZ(E)ations
Juanma Barranquero
lektu at terra.es
Fri Oct 17 04:01:32 EDT 2003
I'm playing with rules, and I wonder if it is posible to define a rule
that will trigger for a specialization of a function.
(In the following examples, the functions are not necesarily useful or
good-style... :)
I have:
count :: (Integral b) => (a -> Bool) -> [a] -> b
count = count' 0
where count' n _ [] = n
count' n f (x:xs) | f x = count' (n+1) f xs
| otherwise = count' n f xs
with b of class Integral and not an Int because it could posibly be used
to count lists with more than maxInt elements (let's say, bytes in a
huge file, or records in a long-lived socket connection, or whatever).
Ok, if I'm not mistaken I can add:
{-# SPECIALIZE count :: (a -> Bool) -> [a] -> Int #-}
and have the compiler add an alternate version of count for uses such
as:
let c :: Int = count even [1..100]
Now, to learn about RULES, I defined:
{-# RULES
"count/generic" forall f g xs. count f (filter g xs) = genericLength (filter (\x -> g x && f x) xs)
#-}
where I'm forced to use genericLength so the types of the LHS and RHS
can match.
Then I wondered: as I have an specialization of count which returns Int,
wouldn't be possible to do:
{-# RULES
"count/int" forall f g xs. count f (filter g xs) = length (filter (\x -> g x && f x) xs)
-#}
Well, the fact is that:
testc1 n = count even (filter (\x -> x `mod` 3 > 0) [1..n])
fires "count/generic" all right, but
testc2 :: Int -> Int
testc2 n = count even (filter (\x -> x `mod` 3 > 0) [1..n])
does not fire "count/int".
I suppose I'm being bitten by User's Guide 7.8.2:
"If more than one rule matches a call, GHC will choose one arbitrarily
to apply."
even if a bit later it says:
"So a rule only matches if the types match too."
Am I understanding right and it's that so?
Thanks,
/L/e/k/t/u
More information about the Glasgow-haskell-users
mailing list