on master help sign in
Fix a bug in unfoldrN, add sensible tests
d1508c3Bryan O'Sullivan
Data/Text/Fusion.hs+2−1
@@ -592,7 +592,8 @@ unfoldr f s0 = Stream next s0 1
592-- first argument to 'unfoldrN'. This function is more efficient than
592-- first argument to 'unfoldrN'. This function is more efficient than
593-- 'unfoldr' when the length of the result is known.
593-- 'unfoldr' when the length of the result is known.
594unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
594unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
595+unfoldrN n f s0 | n < 0 = empty
595−unfoldrN n f s0 = Stream next (0 :!: s0) (n*2)
596+ | otherwise = Stream next (0 :!: s0) (n*2)
596 where
597 where
597 {-# INLINE next #-}
598 {-# INLINE next #-}
598 next (z :!: s) = case f s of
599 next (z :!: s) = case f s of
tests/Properties.hs+9−6
@@ -74,10 +74,13 @@ prop_minimum = L.minimum `eqEP` T.minimum
74prop_scanl f z = L.scanl f z `eqP` (unpack . T.scanl f z)
74prop_scanl f z = L.scanl f z `eqP` (unpack . T.scanl f z)
75
75
76prop_replicate n = L.replicate n `eq` (unpack . T.replicate n)
76prop_replicate n = L.replicate n `eq` (unpack . T.replicate n)
77−prop_unfoldr f = L.unfoldr f `eq` (unpack . T.unfoldr f)
77+prop_unfoldr n = L.unfoldr f `eq` (unpack . T.unfoldr f)
78− where types = f :: Int -> Maybe (Char,Int)
78+ where f c | fromEnum c * 100 > n = Nothing
79+ | otherwise = Just (c, succ c)
80+
79−prop_unfoldrN n f = (L.take n . L.unfoldr f) `eq` (unpack . T.unfoldrN n f)
81+prop_unfoldrN n m = (L.take n . L.unfoldr f) `eq` (unpack . T.unfoldrN n f)
80− where types = f :: Int -> Maybe (Char,Int)
82+ where f c | fromEnum c * 100 > m = Nothing
83+ | otherwise = Just (c, succ c)
81
84
82prop_take n = L.take n `eqP` (unpack . T.take n)
85prop_take n = L.take n `eqP` (unpack . T.take n)
83prop_drop n = L.drop n `eqP` (unpack . T.drop n)
86prop_drop n = L.drop n `eqP` (unpack . T.drop n)
@@ -158,8 +161,8 @@ tests = [
158 ("prop_scanl", mytest prop_scanl),
161 ("prop_scanl", mytest prop_scanl),
159
162
160 ("prop_replicate", mytest prop_replicate),
163 ("prop_replicate", mytest prop_replicate),
161−--("prop_unfoldr", mytest prop_unfoldr),
164+ ("prop_unfoldr", mytest prop_unfoldr),
162−--("prop_unfoldrN", mytest prop_unfoldrN),
165+ ("prop_unfoldrN", mytest prop_unfoldrN),
163
166
164 ("prop_take", mytest prop_take),
167 ("prop_take", mytest prop_take),
165 ("prop_drop", mytest prop_drop),
168 ("prop_drop", mytest prop_drop),
tests/QuickCheckUtils.hs+15−1
@@ -3,13 +3,27 @@
3module QuickCheckUtils where
3module QuickCheckUtils where
4
4
5import Data.List
5import Data.List
6+import Data.Word
6import qualified Data.Text as T
7import qualified Data.Text as T
7import System.IO
8import System.IO
8import System.Random
9import System.Random
9import Test.QuickCheck
10import Test.QuickCheck
10
11
12+integralRandomR :: (Integral a, RandomGen g) => (a,a) -> g -> (a,g)
13+integralRandomR (a,b) g = case randomR (fromIntegral a :: Integer,
14+ fromIntegral b :: Integer) g of
15+ (x,g) -> (fromIntegral x, g)
16+
17+instance Random Word16 where
18+ randomR = integralRandomR
19+ random = randomR (minBound,maxBound)
20+
21+instance Arbitrary Word16 where
22+ arbitrary = choose (minBound,maxBound)
23+ coarbitrary c = variant (fromEnum c `rem` 4)
24+
11instance Arbitrary Char where
25instance Arbitrary Char where
12− arbitrary = oneof [choose ('\0','\55295'), choose ('\57334','\1114111')]
26+ arbitrary = oneof [choose ('\0','\55295'), choose ('\57334','\1114111')]
13 coarbitrary c = variant (fromEnum c `rem` 4)
27 coarbitrary c = variant (fromEnum c `rem` 4)
14
28
15instance Arbitrary T.Text where
29instance Arbitrary T.Text where