Rules to make genericLength strict for Int/Integer lengths, see #2962
authornaur@post11.tele.dk <unknown>
Sat, 7 Feb 2009 18:14:27 +0000 (18:14 +0000)
committernaur@post11.tele.dk <unknown>
Sat, 7 Feb 2009 18:14:27 +0000 (18:14 +0000)
Data/List.hs

index 16cbeb8..bd4e14c 100644 (file)
@@ -568,6 +568,17 @@ genericLength           :: (Num i) => [b] -> i
 genericLength []        =  0
 genericLength (_:l)     =  1 + genericLength l
 
+{-# RULES
+  "genericLengthInt"     genericLength = (strictGenericLength :: [a] -> Int);
+  "genericLengthInteger" genericLength = (strictGenericLength :: [a] -> Integer);
+ #-}
+
+strictGenericLength     :: (Num i) => [b] -> i
+strictGenericLength l   =  gl l 0
+                        where
+                           gl [] a     = a
+                           gl (_:xs) a = let a' = a + 1 in a' `seq` gl xs a'
+
 -- | The 'genericTake' function is an overloaded version of 'take', which
 -- accepts any 'Integral' value as the number of elements to take.
 genericTake             :: (Integral i) => i -> [a] -> [a]