feat(third_party/bazel): Check in rules_haskell from Tweag
This commit is contained in:
parent
2eb1dc26e4
commit
f723b8b878
479 changed files with 51484 additions and 0 deletions
27
third_party/bazel/rules_haskell/examples/vector/tests/Boilerplater.hs
vendored
Normal file
27
third_party/bazel/rules_haskell/examples/vector/tests/Boilerplater.hs
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
module Boilerplater where
|
||||
|
||||
import Test.Framework.Providers.QuickCheck2
|
||||
|
||||
import Language.Haskell.TH
|
||||
|
||||
|
||||
testProperties :: [Name] -> Q Exp
|
||||
testProperties nms = fmap ListE $ sequence [[| testProperty $(stringE prop_name) $(varE nm) |]
|
||||
| nm <- nms
|
||||
, Just prop_name <- [stripPrefix_maybe "prop_" (nameBase nm)]]
|
||||
|
||||
-- This nice clean solution doesn't quite work since I need to use lexically-scoped type
|
||||
-- variables, which aren't supported by Template Haskell. Argh!
|
||||
-- testProperties :: Q [Dec] -> Q Exp
|
||||
-- testProperties mdecs = do
|
||||
-- decs <- mdecs
|
||||
-- property_exprs <- sequence [[| testProperty "$prop_name" $(return $ VarE nm) |]
|
||||
-- | FunD nm _clauses <- decs
|
||||
-- , Just prop_name <- [stripPrefix_maybe "prop_" (nameBase nm)]]
|
||||
-- return $ LetE decs (ListE property_exprs)
|
||||
|
||||
stripPrefix_maybe :: String -> String -> Maybe String
|
||||
stripPrefix_maybe prefix what
|
||||
| what_start == prefix = Just what_end
|
||||
| otherwise = Nothing
|
||||
where (what_start, what_end) = splitAt (length prefix) what
|
||||
30
third_party/bazel/rules_haskell/examples/vector/tests/LICENSE
vendored
Normal file
30
third_party/bazel/rules_haskell/examples/vector/tests/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
Copyright (c) 2009, Max Bolingbroke and Roman Leshchinskiy
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
- Neither name of the University nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
|
||||
GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
15
third_party/bazel/rules_haskell/examples/vector/tests/Main.hs
vendored
Normal file
15
third_party/bazel/rules_haskell/examples/vector/tests/Main.hs
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
module Main (main) where
|
||||
|
||||
import qualified Tests.Vector
|
||||
import qualified Tests.Vector.UnitTests
|
||||
import qualified Tests.Bundle
|
||||
import qualified Tests.Move
|
||||
|
||||
import Test.Framework (defaultMain)
|
||||
|
||||
main :: IO ()
|
||||
main = defaultMain $ Tests.Bundle.tests
|
||||
++ Tests.Vector.tests
|
||||
++ Tests.Vector.UnitTests.tests
|
||||
++ Tests.Move.tests
|
||||
|
||||
3
third_party/bazel/rules_haskell/examples/vector/tests/Setup.hs
vendored
Normal file
3
third_party/bazel/rules_haskell/examples/vector/tests/Setup.hs
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import Distribution.Simple
|
||||
main = defaultMain
|
||||
|
||||
163
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Bundle.hs
vendored
Normal file
163
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Bundle.hs
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
module Tests.Bundle ( tests ) where
|
||||
|
||||
import Boilerplater
|
||||
import Utilities
|
||||
|
||||
import qualified Data.Vector.Fusion.Bundle as S
|
||||
|
||||
import Test.QuickCheck
|
||||
|
||||
import Test.Framework
|
||||
import Test.Framework.Providers.QuickCheck2
|
||||
|
||||
import Text.Show.Functions ()
|
||||
import Data.List (foldl', foldl1', unfoldr, find, findIndex)
|
||||
import System.Random (Random)
|
||||
|
||||
#define COMMON_CONTEXT(a) \
|
||||
VANILLA_CONTEXT(a)
|
||||
|
||||
#define VANILLA_CONTEXT(a) \
|
||||
Eq a, Show a, Arbitrary a, CoArbitrary a, TestData a, Model a ~ a, EqTest a ~ Property
|
||||
|
||||
testSanity :: forall v a. (COMMON_CONTEXT(a)) => S.Bundle v a -> [Test]
|
||||
testSanity _ = [
|
||||
testProperty "fromList.toList == id" prop_fromList_toList,
|
||||
testProperty "toList.fromList == id" prop_toList_fromList
|
||||
]
|
||||
where
|
||||
prop_fromList_toList :: P (S.Bundle v a -> S.Bundle v a)
|
||||
= (S.fromList . S.toList) `eq` id
|
||||
prop_toList_fromList :: P ([a] -> [a])
|
||||
= (S.toList . (S.fromList :: [a] -> S.Bundle v a)) `eq` id
|
||||
|
||||
testPolymorphicFunctions :: forall v a. (COMMON_CONTEXT(a)) => S.Bundle v a -> [Test]
|
||||
testPolymorphicFunctions _ = $(testProperties [
|
||||
'prop_eq,
|
||||
|
||||
'prop_length, 'prop_null,
|
||||
|
||||
'prop_empty, 'prop_singleton, 'prop_replicate,
|
||||
'prop_cons, 'prop_snoc, 'prop_append,
|
||||
|
||||
'prop_head, 'prop_last, 'prop_index,
|
||||
|
||||
'prop_extract, 'prop_init, 'prop_tail, 'prop_take, 'prop_drop,
|
||||
|
||||
'prop_map, 'prop_zipWith, 'prop_zipWith3,
|
||||
'prop_filter, 'prop_takeWhile, 'prop_dropWhile,
|
||||
|
||||
'prop_elem, 'prop_notElem,
|
||||
'prop_find, 'prop_findIndex,
|
||||
|
||||
'prop_foldl, 'prop_foldl1, 'prop_foldl', 'prop_foldl1',
|
||||
'prop_foldr, 'prop_foldr1,
|
||||
|
||||
'prop_prescanl, 'prop_prescanl',
|
||||
'prop_postscanl, 'prop_postscanl',
|
||||
'prop_scanl, 'prop_scanl', 'prop_scanl1, 'prop_scanl1',
|
||||
|
||||
'prop_concatMap,
|
||||
'prop_unfoldr
|
||||
])
|
||||
where
|
||||
-- Prelude
|
||||
prop_eq :: P (S.Bundle v a -> S.Bundle v a -> Bool) = (==) `eq` (==)
|
||||
|
||||
prop_length :: P (S.Bundle v a -> Int) = S.length `eq` length
|
||||
prop_null :: P (S.Bundle v a -> Bool) = S.null `eq` null
|
||||
prop_empty :: P (S.Bundle v a) = S.empty `eq` []
|
||||
prop_singleton :: P (a -> S.Bundle v a) = S.singleton `eq` singleton
|
||||
prop_replicate :: P (Int -> a -> S.Bundle v a)
|
||||
= (\n _ -> n < 1000) ===> S.replicate `eq` replicate
|
||||
prop_cons :: P (a -> S.Bundle v a -> S.Bundle v a) = S.cons `eq` (:)
|
||||
prop_snoc :: P (S.Bundle v a -> a -> S.Bundle v a) = S.snoc `eq` snoc
|
||||
prop_append :: P (S.Bundle v a -> S.Bundle v a -> S.Bundle v a) = (S.++) `eq` (++)
|
||||
|
||||
prop_head :: P (S.Bundle v a -> a) = not . S.null ===> S.head `eq` head
|
||||
prop_last :: P (S.Bundle v a -> a) = not . S.null ===> S.last `eq` last
|
||||
prop_index = \xs ->
|
||||
not (S.null xs) ==>
|
||||
forAll (choose (0, S.length xs-1)) $ \i ->
|
||||
unP prop xs i
|
||||
where
|
||||
prop :: P (S.Bundle v a -> Int -> a) = (S.!!) `eq` (!!)
|
||||
|
||||
prop_extract = \xs ->
|
||||
forAll (choose (0, S.length xs)) $ \i ->
|
||||
forAll (choose (0, S.length xs - i)) $ \n ->
|
||||
unP prop i n xs
|
||||
where
|
||||
prop :: P (Int -> Int -> S.Bundle v a -> S.Bundle v a) = S.slice `eq` slice
|
||||
|
||||
prop_tail :: P (S.Bundle v a -> S.Bundle v a) = not . S.null ===> S.tail `eq` tail
|
||||
prop_init :: P (S.Bundle v a -> S.Bundle v a) = not . S.null ===> S.init `eq` init
|
||||
prop_take :: P (Int -> S.Bundle v a -> S.Bundle v a) = S.take `eq` take
|
||||
prop_drop :: P (Int -> S.Bundle v a -> S.Bundle v a) = S.drop `eq` drop
|
||||
|
||||
prop_map :: P ((a -> a) -> S.Bundle v a -> S.Bundle v a) = S.map `eq` map
|
||||
prop_zipWith :: P ((a -> a -> a) -> S.Bundle v a -> S.Bundle v a -> S.Bundle v a) = S.zipWith `eq` zipWith
|
||||
prop_zipWith3 :: P ((a -> a -> a -> a) -> S.Bundle v a -> S.Bundle v a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.zipWith3 `eq` zipWith3
|
||||
|
||||
prop_filter :: P ((a -> Bool) -> S.Bundle v a -> S.Bundle v a) = S.filter `eq` filter
|
||||
prop_takeWhile :: P ((a -> Bool) -> S.Bundle v a -> S.Bundle v a) = S.takeWhile `eq` takeWhile
|
||||
prop_dropWhile :: P ((a -> Bool) -> S.Bundle v a -> S.Bundle v a) = S.dropWhile `eq` dropWhile
|
||||
|
||||
prop_elem :: P (a -> S.Bundle v a -> Bool) = S.elem `eq` elem
|
||||
prop_notElem :: P (a -> S.Bundle v a -> Bool) = S.notElem `eq` notElem
|
||||
prop_find :: P ((a -> Bool) -> S.Bundle v a -> Maybe a) = S.find `eq` find
|
||||
prop_findIndex :: P ((a -> Bool) -> S.Bundle v a -> Maybe Int)
|
||||
= S.findIndex `eq` findIndex
|
||||
|
||||
prop_foldl :: P ((a -> a -> a) -> a -> S.Bundle v a -> a) = S.foldl `eq` foldl
|
||||
prop_foldl1 :: P ((a -> a -> a) -> S.Bundle v a -> a) = notNullS2 ===>
|
||||
S.foldl1 `eq` foldl1
|
||||
prop_foldl' :: P ((a -> a -> a) -> a -> S.Bundle v a -> a) = S.foldl' `eq` foldl'
|
||||
prop_foldl1' :: P ((a -> a -> a) -> S.Bundle v a -> a) = notNullS2 ===>
|
||||
S.foldl1' `eq` foldl1'
|
||||
prop_foldr :: P ((a -> a -> a) -> a -> S.Bundle v a -> a) = S.foldr `eq` foldr
|
||||
prop_foldr1 :: P ((a -> a -> a) -> S.Bundle v a -> a) = notNullS2 ===>
|
||||
S.foldr1 `eq` foldr1
|
||||
|
||||
prop_prescanl :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.prescanl `eq` prescanl
|
||||
prop_prescanl' :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.prescanl' `eq` prescanl
|
||||
prop_postscanl :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.postscanl `eq` postscanl
|
||||
prop_postscanl' :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.postscanl' `eq` postscanl
|
||||
prop_scanl :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.scanl `eq` scanl
|
||||
prop_scanl' :: P ((a -> a -> a) -> a -> S.Bundle v a -> S.Bundle v a)
|
||||
= S.scanl' `eq` scanl
|
||||
prop_scanl1 :: P ((a -> a -> a) -> S.Bundle v a -> S.Bundle v a) = notNullS2 ===>
|
||||
S.scanl1 `eq` scanl1
|
||||
prop_scanl1' :: P ((a -> a -> a) -> S.Bundle v a -> S.Bundle v a) = notNullS2 ===>
|
||||
S.scanl1' `eq` scanl1
|
||||
|
||||
prop_concatMap = forAll arbitrary $ \xs ->
|
||||
forAll (sized (\n -> resize (n `div` S.length xs) arbitrary)) $ \f -> unP prop f xs
|
||||
where
|
||||
prop :: P ((a -> S.Bundle v a) -> S.Bundle v a -> S.Bundle v a) = S.concatMap `eq` concatMap
|
||||
|
||||
limitUnfolds f (theirs, ours) | ours >= 0
|
||||
, Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1))
|
||||
| otherwise = Nothing
|
||||
prop_unfoldr :: P (Int -> (Int -> Maybe (a,Int)) -> Int -> S.Bundle v a)
|
||||
= (\n f a -> S.unfoldr (limitUnfolds f) (a, n))
|
||||
`eq` (\n f a -> unfoldr (limitUnfolds f) (a, n))
|
||||
|
||||
testBoolFunctions :: forall v. S.Bundle v Bool -> [Test]
|
||||
testBoolFunctions _ = $(testProperties ['prop_and, 'prop_or ])
|
||||
where
|
||||
prop_and :: P (S.Bundle v Bool -> Bool) = S.and `eq` and
|
||||
prop_or :: P (S.Bundle v Bool -> Bool) = S.or `eq` or
|
||||
|
||||
testBundleFunctions = testSanity (undefined :: S.Bundle v Int)
|
||||
++ testPolymorphicFunctions (undefined :: S.Bundle v Int)
|
||||
++ testBoolFunctions (undefined :: S.Bundle v Bool)
|
||||
|
||||
tests = [ testGroup "Data.Vector.Fusion.Bundle" testBundleFunctions ]
|
||||
|
||||
49
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Move.hs
vendored
Normal file
49
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Move.hs
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
module Tests.Move (tests) where
|
||||
|
||||
import Test.QuickCheck
|
||||
import Test.Framework.Providers.QuickCheck2
|
||||
import Test.QuickCheck.Property (Property(..))
|
||||
|
||||
import Utilities ()
|
||||
|
||||
import Control.Monad (replicateM)
|
||||
import Control.Monad.ST (runST)
|
||||
import Data.List (sort,permutations)
|
||||
|
||||
import qualified Data.Vector.Generic as G
|
||||
import qualified Data.Vector.Generic.Mutable as M
|
||||
|
||||
import qualified Data.Vector as V
|
||||
import qualified Data.Vector.Primitive as P
|
||||
import qualified Data.Vector.Storable as S
|
||||
import qualified Data.Vector.Unboxed as U
|
||||
|
||||
basicMove :: G.Vector v a => v a -> Int -> Int -> Int -> v a
|
||||
basicMove v dstOff srcOff len
|
||||
| len > 0 = G.modify (\ mv -> G.copy (M.slice dstOff len mv) (G.slice srcOff len v)) v
|
||||
| otherwise = v
|
||||
|
||||
testMove :: (G.Vector v a, Show (v a), Eq (v a)) => v a -> Property
|
||||
testMove v = G.length v > 0 ==> (MkProperty $ do
|
||||
dstOff <- choose (0, G.length v - 1)
|
||||
srcOff <- choose (0, G.length v - 1)
|
||||
len <- choose (1, G.length v - max dstOff srcOff)
|
||||
expected <- return $ basicMove v dstOff srcOff len
|
||||
actual <- return $ G.modify (\ mv -> M.move (M.slice dstOff len mv) (M.slice srcOff len mv)) v
|
||||
unProperty $ counterexample ("Move: " ++ show (v, dstOff, srcOff, len)) (expected == actual))
|
||||
|
||||
checkPermutations :: Int -> Bool
|
||||
checkPermutations n = runST $ do
|
||||
vec <- U.thaw (U.fromList [1..n])
|
||||
res <- replicateM (product [1..n]) $ M.nextPermutation vec >> U.freeze vec >>= return . U.toList
|
||||
return $! ([1..n] : res) == sort (permutations [1..n]) ++ [[n,n-1..1]]
|
||||
|
||||
testPermutations :: Bool
|
||||
testPermutations = all checkPermutations [1..7]
|
||||
|
||||
tests =
|
||||
[testProperty "Data.Vector.Mutable (Move)" (testMove :: V.Vector Int -> Property),
|
||||
testProperty "Data.Vector.Primitive.Mutable (Move)" (testMove :: P.Vector Int -> Property),
|
||||
testProperty "Data.Vector.Unboxed.Mutable (Move)" (testMove :: U.Vector Int -> Property),
|
||||
testProperty "Data.Vector.Storable.Mutable (Move)" (testMove :: S.Vector Int -> Property),
|
||||
testProperty "Data.Vector.Generic.Mutable (nextPermutation)" testPermutations]
|
||||
706
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Vector.hs
vendored
Normal file
706
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Vector.hs
vendored
Normal file
|
|
@ -0,0 +1,706 @@
|
|||
{-# LANGUAGE ConstraintKinds #-}
|
||||
module Tests.Vector (tests) where
|
||||
|
||||
import Boilerplater
|
||||
import Utilities as Util
|
||||
|
||||
import Data.Functor.Identity
|
||||
import qualified Data.Traversable as T (Traversable(..))
|
||||
import Data.Foldable (Foldable(foldMap))
|
||||
|
||||
import qualified Data.Vector.Generic as V
|
||||
import qualified Data.Vector
|
||||
import qualified Data.Vector.Primitive
|
||||
import qualified Data.Vector.Storable
|
||||
import qualified Data.Vector.Unboxed
|
||||
import qualified Data.Vector.Fusion.Bundle as S
|
||||
|
||||
import Test.QuickCheck
|
||||
|
||||
import Test.Framework
|
||||
import Test.Framework.Providers.QuickCheck2
|
||||
|
||||
import Text.Show.Functions ()
|
||||
import Data.List
|
||||
import Data.Monoid
|
||||
import qualified Control.Applicative as Applicative
|
||||
import System.Random (Random)
|
||||
|
||||
import Data.Functor.Identity
|
||||
import Control.Monad.Trans.Writer
|
||||
|
||||
import Control.Monad.Zip
|
||||
|
||||
type CommonContext a v = (VanillaContext a, VectorContext a v)
|
||||
type VanillaContext a = ( Eq a , Show a, Arbitrary a, CoArbitrary a
|
||||
, TestData a, Model a ~ a, EqTest a ~ Property)
|
||||
type VectorContext a v = ( Eq (v a), Show (v a), Arbitrary (v a), CoArbitrary (v a)
|
||||
, TestData (v a), Model (v a) ~ [a], EqTest (v a) ~ Property, V.Vector v a)
|
||||
|
||||
-- TODO: implement Vector equivalents of list functions for some of the commented out properties
|
||||
|
||||
-- TODO: test and implement some of these other Prelude functions:
|
||||
-- mapM *
|
||||
-- mapM_ *
|
||||
-- sequence
|
||||
-- sequence_
|
||||
-- sum *
|
||||
-- product *
|
||||
-- scanl *
|
||||
-- scanl1 *
|
||||
-- scanr *
|
||||
-- scanr1 *
|
||||
-- lookup *
|
||||
-- lines
|
||||
-- words
|
||||
-- unlines
|
||||
-- unwords
|
||||
-- NB: this is an exhaustive list of all Prelude list functions that make sense for vectors.
|
||||
-- Ones with *s are the most plausible candidates.
|
||||
|
||||
-- TODO: add tests for the other extra functions
|
||||
-- IVector exports still needing tests:
|
||||
-- copy,
|
||||
-- slice,
|
||||
-- (//), update, bpermute,
|
||||
-- prescanl, prescanl',
|
||||
-- new,
|
||||
-- unsafeSlice, unsafeIndex,
|
||||
-- vlength, vnew
|
||||
|
||||
-- TODO: test non-IVector stuff?
|
||||
|
||||
#if !MIN_VERSION_base(4,7,0)
|
||||
instance Foldable ((,) a) where
|
||||
foldMap f (_, b) = f b
|
||||
|
||||
instance T.Traversable ((,) a) where
|
||||
traverse f (a, b) = fmap ((,) a) $ f b
|
||||
#endif
|
||||
|
||||
testSanity :: forall a v. (CommonContext a v) => v a -> [Test]
|
||||
testSanity _ = [
|
||||
testProperty "fromList.toList == id" prop_fromList_toList,
|
||||
testProperty "toList.fromList == id" prop_toList_fromList,
|
||||
testProperty "unstream.stream == id" prop_unstream_stream,
|
||||
testProperty "stream.unstream == id" prop_stream_unstream
|
||||
]
|
||||
where
|
||||
prop_fromList_toList (v :: v a) = (V.fromList . V.toList) v == v
|
||||
prop_toList_fromList (l :: [a]) = ((V.toList :: v a -> [a]) . V.fromList) l == l
|
||||
prop_unstream_stream (v :: v a) = (V.unstream . V.stream) v == v
|
||||
prop_stream_unstream (s :: S.Bundle v a) = ((V.stream :: v a -> S.Bundle v a) . V.unstream) s == s
|
||||
|
||||
testPolymorphicFunctions :: forall a v. (CommonContext a v, VectorContext Int v) => v a -> [Test]
|
||||
testPolymorphicFunctions _ = $(testProperties [
|
||||
'prop_eq,
|
||||
|
||||
-- Length information
|
||||
'prop_length, 'prop_null,
|
||||
|
||||
-- Indexing (FIXME)
|
||||
'prop_index, 'prop_safeIndex, 'prop_head, 'prop_last,
|
||||
'prop_unsafeIndex, 'prop_unsafeHead, 'prop_unsafeLast,
|
||||
|
||||
-- Monadic indexing (FIXME)
|
||||
{- 'prop_indexM, 'prop_headM, 'prop_lastM,
|
||||
'prop_unsafeIndexM, 'prop_unsafeHeadM, 'prop_unsafeLastM, -}
|
||||
|
||||
-- Subvectors (FIXME)
|
||||
'prop_slice, 'prop_init, 'prop_tail, 'prop_take, 'prop_drop,
|
||||
'prop_splitAt,
|
||||
{- 'prop_unsafeSlice, 'prop_unsafeInit, 'prop_unsafeTail,
|
||||
'prop_unsafeTake, 'prop_unsafeDrop, -}
|
||||
|
||||
-- Initialisation (FIXME)
|
||||
'prop_empty, 'prop_singleton, 'prop_replicate,
|
||||
'prop_generate, 'prop_iterateN, 'prop_iterateNM,
|
||||
|
||||
-- Monadic initialisation (FIXME)
|
||||
'prop_createT,
|
||||
{- 'prop_replicateM, 'prop_generateM, 'prop_create, -}
|
||||
|
||||
-- Unfolding
|
||||
'prop_unfoldr, 'prop_unfoldrN, 'prop_unfoldrM, 'prop_unfoldrNM,
|
||||
'prop_constructN, 'prop_constructrN,
|
||||
|
||||
-- Enumeration? (FIXME?)
|
||||
|
||||
-- Concatenation (FIXME)
|
||||
'prop_cons, 'prop_snoc, 'prop_append,
|
||||
'prop_concat,
|
||||
|
||||
-- Restricting memory usage
|
||||
'prop_force,
|
||||
|
||||
|
||||
-- Bulk updates (FIXME)
|
||||
'prop_upd,
|
||||
{- 'prop_update, 'prop_update_,
|
||||
'prop_unsafeUpd, 'prop_unsafeUpdate, 'prop_unsafeUpdate_, -}
|
||||
|
||||
-- Accumulations (FIXME)
|
||||
'prop_accum,
|
||||
{- 'prop_accumulate, 'prop_accumulate_,
|
||||
'prop_unsafeAccum, 'prop_unsafeAccumulate, 'prop_unsafeAccumulate_, -}
|
||||
|
||||
-- Permutations
|
||||
'prop_reverse, 'prop_backpermute,
|
||||
{- 'prop_unsafeBackpermute, -}
|
||||
|
||||
-- Elementwise indexing
|
||||
{- 'prop_indexed, -}
|
||||
|
||||
-- Mapping
|
||||
'prop_map, 'prop_imap, 'prop_concatMap,
|
||||
|
||||
-- Monadic mapping
|
||||
{- 'prop_mapM, 'prop_mapM_, 'prop_forM, 'prop_forM_, -}
|
||||
'prop_imapM, 'prop_imapM_,
|
||||
|
||||
-- Zipping
|
||||
'prop_zipWith, 'prop_zipWith3, {- ... -}
|
||||
'prop_izipWith, 'prop_izipWith3, {- ... -}
|
||||
'prop_izipWithM, 'prop_izipWithM_,
|
||||
{- 'prop_zip, ... -}
|
||||
|
||||
-- Monadic zipping
|
||||
{- 'prop_zipWithM, 'prop_zipWithM_, -}
|
||||
|
||||
-- Unzipping
|
||||
{- 'prop_unzip, ... -}
|
||||
|
||||
-- Filtering
|
||||
'prop_filter, 'prop_ifilter, {- prop_filterM, -}
|
||||
'prop_uniq,
|
||||
'prop_mapMaybe, 'prop_imapMaybe,
|
||||
'prop_takeWhile, 'prop_dropWhile,
|
||||
|
||||
-- Paritioning
|
||||
'prop_partition, {- 'prop_unstablePartition, -}
|
||||
'prop_span, 'prop_break,
|
||||
|
||||
-- Searching
|
||||
'prop_elem, 'prop_notElem,
|
||||
'prop_find, 'prop_findIndex, 'prop_findIndices,
|
||||
'prop_elemIndex, 'prop_elemIndices,
|
||||
|
||||
-- Folding
|
||||
'prop_foldl, 'prop_foldl1, 'prop_foldl', 'prop_foldl1',
|
||||
'prop_foldr, 'prop_foldr1, 'prop_foldr', 'prop_foldr1',
|
||||
'prop_ifoldl, 'prop_ifoldl', 'prop_ifoldr, 'prop_ifoldr',
|
||||
'prop_ifoldM, 'prop_ifoldM', 'prop_ifoldM_, 'prop_ifoldM'_,
|
||||
|
||||
-- Specialised folds
|
||||
'prop_all, 'prop_any,
|
||||
{- 'prop_maximumBy, 'prop_minimumBy,
|
||||
'prop_maxIndexBy, 'prop_minIndexBy, -}
|
||||
|
||||
-- Monadic folds
|
||||
{- ... -}
|
||||
|
||||
-- Monadic sequencing
|
||||
{- ... -}
|
||||
|
||||
-- Scans
|
||||
'prop_prescanl, 'prop_prescanl',
|
||||
'prop_postscanl, 'prop_postscanl',
|
||||
'prop_scanl, 'prop_scanl', 'prop_scanl1, 'prop_scanl1',
|
||||
'prop_iscanl, 'prop_iscanl',
|
||||
|
||||
'prop_prescanr, 'prop_prescanr',
|
||||
'prop_postscanr, 'prop_postscanr',
|
||||
'prop_scanr, 'prop_scanr', 'prop_scanr1, 'prop_scanr1',
|
||||
'prop_iscanr, 'prop_iscanr'
|
||||
])
|
||||
where
|
||||
-- Prelude
|
||||
prop_eq :: P (v a -> v a -> Bool) = (==) `eq` (==)
|
||||
|
||||
prop_length :: P (v a -> Int) = V.length `eq` length
|
||||
prop_null :: P (v a -> Bool) = V.null `eq` null
|
||||
|
||||
prop_empty :: P (v a) = V.empty `eq` []
|
||||
prop_singleton :: P (a -> v a) = V.singleton `eq` singleton
|
||||
prop_replicate :: P (Int -> a -> v a)
|
||||
= (\n _ -> n < 1000) ===> V.replicate `eq` replicate
|
||||
prop_cons :: P (a -> v a -> v a) = V.cons `eq` (:)
|
||||
prop_snoc :: P (v a -> a -> v a) = V.snoc `eq` snoc
|
||||
prop_append :: P (v a -> v a -> v a) = (V.++) `eq` (++)
|
||||
prop_concat :: P ([v a] -> v a) = V.concat `eq` concat
|
||||
prop_force :: P (v a -> v a) = V.force `eq` id
|
||||
prop_generate :: P (Int -> (Int -> a) -> v a)
|
||||
= (\n _ -> n < 1000) ===> V.generate `eq` Util.generate
|
||||
prop_iterateN :: P (Int -> (a -> a) -> a -> v a)
|
||||
= (\n _ _ -> n < 1000) ===> V.iterateN `eq` (\n f -> take n . iterate f)
|
||||
prop_iterateNM :: P (Int -> (a -> Writer [Int] a) -> a -> Writer [Int] (v a))
|
||||
= (\n _ _ -> n < 1000) ===> V.iterateNM `eq` Util.iterateNM
|
||||
prop_createT :: P ((a, v a) -> (a, v a))
|
||||
prop_createT = (\v -> V.createT (T.mapM V.thaw v)) `eq` id
|
||||
|
||||
prop_head :: P (v a -> a) = not . V.null ===> V.head `eq` head
|
||||
prop_last :: P (v a -> a) = not . V.null ===> V.last `eq` last
|
||||
prop_index = \xs ->
|
||||
not (V.null xs) ==>
|
||||
forAll (choose (0, V.length xs-1)) $ \i ->
|
||||
unP prop xs i
|
||||
where
|
||||
prop :: P (v a -> Int -> a) = (V.!) `eq` (!!)
|
||||
prop_safeIndex :: P (v a -> Int -> Maybe a) = (V.!?) `eq` fn
|
||||
where
|
||||
fn xs i = case drop i xs of
|
||||
x:_ | i >= 0 -> Just x
|
||||
_ -> Nothing
|
||||
prop_unsafeHead :: P (v a -> a) = not . V.null ===> V.unsafeHead `eq` head
|
||||
prop_unsafeLast :: P (v a -> a) = not . V.null ===> V.unsafeLast `eq` last
|
||||
prop_unsafeIndex = \xs ->
|
||||
not (V.null xs) ==>
|
||||
forAll (choose (0, V.length xs-1)) $ \i ->
|
||||
unP prop xs i
|
||||
where
|
||||
prop :: P (v a -> Int -> a) = V.unsafeIndex `eq` (!!)
|
||||
|
||||
prop_slice = \xs ->
|
||||
forAll (choose (0, V.length xs)) $ \i ->
|
||||
forAll (choose (0, V.length xs - i)) $ \n ->
|
||||
unP prop i n xs
|
||||
where
|
||||
prop :: P (Int -> Int -> v a -> v a) = V.slice `eq` slice
|
||||
|
||||
prop_tail :: P (v a -> v a) = not . V.null ===> V.tail `eq` tail
|
||||
prop_init :: P (v a -> v a) = not . V.null ===> V.init `eq` init
|
||||
prop_take :: P (Int -> v a -> v a) = V.take `eq` take
|
||||
prop_drop :: P (Int -> v a -> v a) = V.drop `eq` drop
|
||||
prop_splitAt :: P (Int -> v a -> (v a, v a)) = V.splitAt `eq` splitAt
|
||||
|
||||
prop_accum = \f xs ->
|
||||
forAll (index_value_pairs (V.length xs)) $ \ps ->
|
||||
unP prop f xs ps
|
||||
where
|
||||
prop :: P ((a -> a -> a) -> v a -> [(Int,a)] -> v a)
|
||||
= V.accum `eq` accum
|
||||
|
||||
prop_upd = \xs ->
|
||||
forAll (index_value_pairs (V.length xs)) $ \ps ->
|
||||
unP prop xs ps
|
||||
where
|
||||
prop :: P (v a -> [(Int,a)] -> v a) = (V.//) `eq` (//)
|
||||
|
||||
prop_backpermute = \xs ->
|
||||
forAll (indices (V.length xs)) $ \is ->
|
||||
unP prop xs (V.fromList is)
|
||||
where
|
||||
prop :: P (v a -> v Int -> v a) = V.backpermute `eq` backpermute
|
||||
|
||||
prop_reverse :: P (v a -> v a) = V.reverse `eq` reverse
|
||||
|
||||
prop_map :: P ((a -> a) -> v a -> v a) = V.map `eq` map
|
||||
prop_zipWith :: P ((a -> a -> a) -> v a -> v a -> v a) = V.zipWith `eq` zipWith
|
||||
prop_zipWith3 :: P ((a -> a -> a -> a) -> v a -> v a -> v a -> v a)
|
||||
= V.zipWith3 `eq` zipWith3
|
||||
prop_imap :: P ((Int -> a -> a) -> v a -> v a) = V.imap `eq` imap
|
||||
prop_imapM :: P ((Int -> a -> Identity a) -> v a -> Identity (v a))
|
||||
= V.imapM `eq` imapM
|
||||
prop_imapM_ :: P ((Int -> a -> Writer [a] ()) -> v a -> Writer [a] ())
|
||||
= V.imapM_ `eq` imapM_
|
||||
prop_izipWith :: P ((Int -> a -> a -> a) -> v a -> v a -> v a) = V.izipWith `eq` izipWith
|
||||
prop_izipWithM :: P ((Int -> a -> a -> Identity a) -> v a -> v a -> Identity (v a))
|
||||
= V.izipWithM `eq` izipWithM
|
||||
prop_izipWithM_ :: P ((Int -> a -> a -> Writer [a] ()) -> v a -> v a -> Writer [a] ())
|
||||
= V.izipWithM_ `eq` izipWithM_
|
||||
prop_izipWith3 :: P ((Int -> a -> a -> a -> a) -> v a -> v a -> v a -> v a)
|
||||
= V.izipWith3 `eq` izipWith3
|
||||
|
||||
prop_filter :: P ((a -> Bool) -> v a -> v a) = V.filter `eq` filter
|
||||
prop_ifilter :: P ((Int -> a -> Bool) -> v a -> v a) = V.ifilter `eq` ifilter
|
||||
prop_mapMaybe :: P ((a -> Maybe a) -> v a -> v a) = V.mapMaybe `eq` mapMaybe
|
||||
prop_imapMaybe :: P ((Int -> a -> Maybe a) -> v a -> v a) = V.imapMaybe `eq` imapMaybe
|
||||
prop_takeWhile :: P ((a -> Bool) -> v a -> v a) = V.takeWhile `eq` takeWhile
|
||||
prop_dropWhile :: P ((a -> Bool) -> v a -> v a) = V.dropWhile `eq` dropWhile
|
||||
prop_partition :: P ((a -> Bool) -> v a -> (v a, v a))
|
||||
= V.partition `eq` partition
|
||||
prop_span :: P ((a -> Bool) -> v a -> (v a, v a)) = V.span `eq` span
|
||||
prop_break :: P ((a -> Bool) -> v a -> (v a, v a)) = V.break `eq` break
|
||||
|
||||
prop_elem :: P (a -> v a -> Bool) = V.elem `eq` elem
|
||||
prop_notElem :: P (a -> v a -> Bool) = V.notElem `eq` notElem
|
||||
prop_find :: P ((a -> Bool) -> v a -> Maybe a) = V.find `eq` find
|
||||
prop_findIndex :: P ((a -> Bool) -> v a -> Maybe Int)
|
||||
= V.findIndex `eq` findIndex
|
||||
prop_findIndices :: P ((a -> Bool) -> v a -> v Int)
|
||||
= V.findIndices `eq` findIndices
|
||||
prop_elemIndex :: P (a -> v a -> Maybe Int) = V.elemIndex `eq` elemIndex
|
||||
prop_elemIndices :: P (a -> v a -> v Int) = V.elemIndices `eq` elemIndices
|
||||
|
||||
prop_foldl :: P ((a -> a -> a) -> a -> v a -> a) = V.foldl `eq` foldl
|
||||
prop_foldl1 :: P ((a -> a -> a) -> v a -> a) = notNull2 ===>
|
||||
V.foldl1 `eq` foldl1
|
||||
prop_foldl' :: P ((a -> a -> a) -> a -> v a -> a) = V.foldl' `eq` foldl'
|
||||
prop_foldl1' :: P ((a -> a -> a) -> v a -> a) = notNull2 ===>
|
||||
V.foldl1' `eq` foldl1'
|
||||
prop_foldr :: P ((a -> a -> a) -> a -> v a -> a) = V.foldr `eq` foldr
|
||||
prop_foldr1 :: P ((a -> a -> a) -> v a -> a) = notNull2 ===>
|
||||
V.foldr1 `eq` foldr1
|
||||
prop_foldr' :: P ((a -> a -> a) -> a -> v a -> a) = V.foldr' `eq` foldr
|
||||
prop_foldr1' :: P ((a -> a -> a) -> v a -> a) = notNull2 ===>
|
||||
V.foldr1' `eq` foldr1
|
||||
prop_ifoldl :: P ((a -> Int -> a -> a) -> a -> v a -> a)
|
||||
= V.ifoldl `eq` ifoldl
|
||||
prop_ifoldl' :: P ((a -> Int -> a -> a) -> a -> v a -> a)
|
||||
= V.ifoldl' `eq` ifoldl
|
||||
prop_ifoldr :: P ((Int -> a -> a -> a) -> a -> v a -> a)
|
||||
= V.ifoldr `eq` ifoldr
|
||||
prop_ifoldr' :: P ((Int -> a -> a -> a) -> a -> v a -> a)
|
||||
= V.ifoldr' `eq` ifoldr
|
||||
prop_ifoldM :: P ((a -> Int -> a -> Identity a) -> a -> v a -> Identity a)
|
||||
= V.ifoldM `eq` ifoldM
|
||||
prop_ifoldM' :: P ((a -> Int -> a -> Identity a) -> a -> v a -> Identity a)
|
||||
= V.ifoldM' `eq` ifoldM
|
||||
prop_ifoldM_ :: P ((() -> Int -> a -> Writer [a] ()) -> () -> v a -> Writer [a] ())
|
||||
= V.ifoldM_ `eq` ifoldM_
|
||||
prop_ifoldM'_ :: P ((() -> Int -> a -> Writer [a] ()) -> () -> v a -> Writer [a] ())
|
||||
= V.ifoldM'_ `eq` ifoldM_
|
||||
|
||||
prop_all :: P ((a -> Bool) -> v a -> Bool) = V.all `eq` all
|
||||
prop_any :: P ((a -> Bool) -> v a -> Bool) = V.any `eq` any
|
||||
|
||||
prop_prescanl :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.prescanl `eq` prescanl
|
||||
prop_prescanl' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.prescanl' `eq` prescanl
|
||||
prop_postscanl :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.postscanl `eq` postscanl
|
||||
prop_postscanl' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.postscanl' `eq` postscanl
|
||||
prop_scanl :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.scanl `eq` scanl
|
||||
prop_scanl' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.scanl' `eq` scanl
|
||||
prop_scanl1 :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
|
||||
V.scanl1 `eq` scanl1
|
||||
prop_scanl1' :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
|
||||
V.scanl1' `eq` scanl1
|
||||
prop_iscanl :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
|
||||
= V.iscanl `eq` iscanl
|
||||
prop_iscanl' :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
|
||||
= V.iscanl' `eq` iscanl
|
||||
|
||||
prop_prescanr :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.prescanr `eq` prescanr
|
||||
prop_prescanr' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.prescanr' `eq` prescanr
|
||||
prop_postscanr :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.postscanr `eq` postscanr
|
||||
prop_postscanr' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.postscanr' `eq` postscanr
|
||||
prop_scanr :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.scanr `eq` scanr
|
||||
prop_scanr' :: P ((a -> a -> a) -> a -> v a -> v a)
|
||||
= V.scanr' `eq` scanr
|
||||
prop_iscanr :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
|
||||
= V.iscanr `eq` iscanr
|
||||
prop_iscanr' :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
|
||||
= V.iscanr' `eq` iscanr
|
||||
prop_scanr1 :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
|
||||
V.scanr1 `eq` scanr1
|
||||
prop_scanr1' :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
|
||||
V.scanr1' `eq` scanr1
|
||||
|
||||
prop_concatMap = forAll arbitrary $ \xs ->
|
||||
forAll (sized (\n -> resize (n `div` V.length xs) arbitrary)) $ \f -> unP prop f xs
|
||||
where
|
||||
prop :: P ((a -> v a) -> v a -> v a) = V.concatMap `eq` concatMap
|
||||
|
||||
prop_uniq :: P (v a -> v a)
|
||||
= V.uniq `eq` (map head . group)
|
||||
--prop_span = (V.span :: (a -> Bool) -> v a -> (v a, v a)) `eq2` span
|
||||
--prop_break = (V.break :: (a -> Bool) -> v a -> (v a, v a)) `eq2` break
|
||||
--prop_splitAt = (V.splitAt :: Int -> v a -> (v a, v a)) `eq2` splitAt
|
||||
--prop_all = (V.all :: (a -> Bool) -> v a -> Bool) `eq2` all
|
||||
--prop_any = (V.any :: (a -> Bool) -> v a -> Bool) `eq2` any
|
||||
|
||||
-- Data.List
|
||||
--prop_findIndices = V.findIndices `eq2` (findIndices :: (a -> Bool) -> v a -> v Int)
|
||||
--prop_isPrefixOf = V.isPrefixOf `eq2` (isPrefixOf :: v a -> v a -> Bool)
|
||||
--prop_elemIndex = V.elemIndex `eq2` (elemIndex :: a -> v a -> Maybe Int)
|
||||
--prop_elemIndices = V.elemIndices `eq2` (elemIndices :: a -> v a -> v Int)
|
||||
--
|
||||
--prop_mapAccumL = eq3
|
||||
-- (V.mapAccumL :: (X -> W -> (X,W)) -> X -> B -> (X, B))
|
||||
-- ( mapAccumL :: (X -> W -> (X,W)) -> X -> [W] -> (X, [W]))
|
||||
--
|
||||
--prop_mapAccumR = eq3
|
||||
-- (V.mapAccumR :: (X -> W -> (X,W)) -> X -> B -> (X, B))
|
||||
-- ( mapAccumR :: (X -> W -> (X,W)) -> X -> [W] -> (X, [W]))
|
||||
|
||||
-- Because the vectors are strict, we need to be totally sure that the unfold eventually terminates. This
|
||||
-- is achieved by injecting our own bit of state into the unfold - the maximum number of unfolds allowed.
|
||||
limitUnfolds f (theirs, ours)
|
||||
| ours > 0
|
||||
, Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1))
|
||||
| otherwise = Nothing
|
||||
limitUnfoldsM f (theirs, ours)
|
||||
| ours > 0 = do r <- f theirs
|
||||
return $ (\(a,b) -> (a,(b,ours - 1))) `fmap` r
|
||||
| otherwise = return Nothing
|
||||
|
||||
|
||||
prop_unfoldr :: P (Int -> (Int -> Maybe (a,Int)) -> Int -> v a)
|
||||
= (\n f a -> V.unfoldr (limitUnfolds f) (a, n))
|
||||
`eq` (\n f a -> unfoldr (limitUnfolds f) (a, n))
|
||||
prop_unfoldrN :: P (Int -> (Int -> Maybe (a,Int)) -> Int -> v a)
|
||||
= V.unfoldrN `eq` (\n f a -> unfoldr (limitUnfolds f) (a, n))
|
||||
prop_unfoldrM :: P (Int -> (Int -> Writer [Int] (Maybe (a,Int))) -> Int -> Writer [Int] (v a))
|
||||
= (\n f a -> V.unfoldrM (limitUnfoldsM f) (a,n))
|
||||
`eq` (\n f a -> Util.unfoldrM (limitUnfoldsM f) (a, n))
|
||||
prop_unfoldrNM :: P (Int -> (Int -> Writer [Int] (Maybe (a,Int))) -> Int -> Writer [Int] (v a))
|
||||
= V.unfoldrNM `eq` (\n f a -> Util.unfoldrM (limitUnfoldsM f) (a, n))
|
||||
|
||||
prop_constructN = \f -> forAll (choose (0,20)) $ \n -> unP prop n f
|
||||
where
|
||||
prop :: P (Int -> (v a -> a) -> v a) = V.constructN `eq` constructN []
|
||||
|
||||
constructN xs 0 _ = xs
|
||||
constructN xs n f = constructN (xs ++ [f xs]) (n-1) f
|
||||
|
||||
prop_constructrN = \f -> forAll (choose (0,20)) $ \n -> unP prop n f
|
||||
where
|
||||
prop :: P (Int -> (v a -> a) -> v a) = V.constructrN `eq` constructrN []
|
||||
|
||||
constructrN xs 0 _ = xs
|
||||
constructrN xs n f = constructrN (f xs : xs) (n-1) f
|
||||
|
||||
testTuplyFunctions:: forall a v. (CommonContext a v, VectorContext (a, a) v, VectorContext (a, a, a) v) => v a -> [Test]
|
||||
testTuplyFunctions _ = $(testProperties [ 'prop_zip, 'prop_zip3
|
||||
, 'prop_unzip, 'prop_unzip3
|
||||
, 'prop_mzip, 'prop_munzip
|
||||
])
|
||||
where
|
||||
prop_zip :: P (v a -> v a -> v (a, a)) = V.zip `eq` zip
|
||||
prop_zip3 :: P (v a -> v a -> v a -> v (a, a, a)) = V.zip3 `eq` zip3
|
||||
prop_unzip :: P (v (a, a) -> (v a, v a)) = V.unzip `eq` unzip
|
||||
prop_unzip3 :: P (v (a, a, a) -> (v a, v a, v a)) = V.unzip3 `eq` unzip3
|
||||
prop_mzip :: P (Data.Vector.Vector a -> Data.Vector.Vector a -> Data.Vector.Vector (a, a))
|
||||
= mzip `eq` zip
|
||||
prop_munzip :: P (Data.Vector.Vector (a, a) -> (Data.Vector.Vector a, Data.Vector.Vector a))
|
||||
= munzip `eq` unzip
|
||||
|
||||
testOrdFunctions :: forall a v. (CommonContext a v, Ord a, Ord (v a)) => v a -> [Test]
|
||||
testOrdFunctions _ = $(testProperties
|
||||
['prop_compare,
|
||||
'prop_maximum, 'prop_minimum,
|
||||
'prop_minIndex, 'prop_maxIndex ])
|
||||
where
|
||||
prop_compare :: P (v a -> v a -> Ordering) = compare `eq` compare
|
||||
prop_maximum :: P (v a -> a) = not . V.null ===> V.maximum `eq` maximum
|
||||
prop_minimum :: P (v a -> a) = not . V.null ===> V.minimum `eq` minimum
|
||||
prop_minIndex :: P (v a -> Int) = not . V.null ===> V.minIndex `eq` minIndex
|
||||
prop_maxIndex :: P (v a -> Int) = not . V.null ===> V.maxIndex `eq` maxIndex
|
||||
|
||||
testEnumFunctions :: forall a v. (CommonContext a v, Enum a, Ord a, Num a, Random a) => v a -> [Test]
|
||||
testEnumFunctions _ = $(testProperties
|
||||
[ 'prop_enumFromN, 'prop_enumFromThenN,
|
||||
'prop_enumFromTo, 'prop_enumFromThenTo])
|
||||
where
|
||||
prop_enumFromN :: P (a -> Int -> v a)
|
||||
= (\_ n -> n < 1000)
|
||||
===> V.enumFromN `eq` (\x n -> take n $ scanl (+) x $ repeat 1)
|
||||
|
||||
prop_enumFromThenN :: P (a -> a -> Int -> v a)
|
||||
= (\_ _ n -> n < 1000)
|
||||
===> V.enumFromStepN `eq` (\x y n -> take n $ scanl (+) x $ repeat y)
|
||||
|
||||
prop_enumFromTo = \m ->
|
||||
forAll (choose (-2,100)) $ \n ->
|
||||
unP prop m (m+n)
|
||||
where
|
||||
prop :: P (a -> a -> v a) = V.enumFromTo `eq` enumFromTo
|
||||
|
||||
prop_enumFromThenTo = \i j ->
|
||||
j /= i ==>
|
||||
forAll (choose (ks i j)) $ \k ->
|
||||
unP prop i j k
|
||||
where
|
||||
prop :: P (a -> a -> a -> v a) = V.enumFromThenTo `eq` enumFromThenTo
|
||||
|
||||
ks i j | j < i = (i-d*100, i+d*2)
|
||||
| otherwise = (i-d*2, i+d*100)
|
||||
where
|
||||
d = abs (j-i)
|
||||
|
||||
testMonoidFunctions :: forall a v. (CommonContext a v, Monoid (v a)) => v a -> [Test]
|
||||
testMonoidFunctions _ = $(testProperties
|
||||
[ 'prop_mempty, 'prop_mappend, 'prop_mconcat ])
|
||||
where
|
||||
prop_mempty :: P (v a) = mempty `eq` mempty
|
||||
prop_mappend :: P (v a -> v a -> v a) = mappend `eq` mappend
|
||||
prop_mconcat :: P ([v a] -> v a) = mconcat `eq` mconcat
|
||||
|
||||
testFunctorFunctions :: forall a v. (CommonContext a v, Functor v) => v a -> [Test]
|
||||
testFunctorFunctions _ = $(testProperties
|
||||
[ 'prop_fmap ])
|
||||
where
|
||||
prop_fmap :: P ((a -> a) -> v a -> v a) = fmap `eq` fmap
|
||||
|
||||
testMonadFunctions :: forall a v. (CommonContext a v, Monad v) => v a -> [Test]
|
||||
testMonadFunctions _ = $(testProperties
|
||||
[ 'prop_return, 'prop_bind ])
|
||||
where
|
||||
prop_return :: P (a -> v a) = return `eq` return
|
||||
prop_bind :: P (v a -> (a -> v a) -> v a) = (>>=) `eq` (>>=)
|
||||
|
||||
testApplicativeFunctions :: forall a v. (CommonContext a v, V.Vector v (a -> a), Applicative.Applicative v) => v a -> [Test]
|
||||
testApplicativeFunctions _ = $(testProperties
|
||||
[ 'prop_applicative_pure, 'prop_applicative_appl ])
|
||||
where
|
||||
prop_applicative_pure :: P (a -> v a)
|
||||
= Applicative.pure `eq` Applicative.pure
|
||||
prop_applicative_appl :: [a -> a] -> P (v a -> v a)
|
||||
= \fs -> (Applicative.<*>) (V.fromList fs) `eq` (Applicative.<*>) fs
|
||||
|
||||
testAlternativeFunctions :: forall a v. (CommonContext a v, Applicative.Alternative v) => v a -> [Test]
|
||||
testAlternativeFunctions _ = $(testProperties
|
||||
[ 'prop_alternative_empty, 'prop_alternative_or ])
|
||||
where
|
||||
prop_alternative_empty :: P (v a) = Applicative.empty `eq` Applicative.empty
|
||||
prop_alternative_or :: P (v a -> v a -> v a)
|
||||
= (Applicative.<|>) `eq` (Applicative.<|>)
|
||||
|
||||
testBoolFunctions :: forall v. (CommonContext Bool v) => v Bool -> [Test]
|
||||
testBoolFunctions _ = $(testProperties ['prop_and, 'prop_or])
|
||||
where
|
||||
prop_and :: P (v Bool -> Bool) = V.and `eq` and
|
||||
prop_or :: P (v Bool -> Bool) = V.or `eq` or
|
||||
|
||||
testNumFunctions :: forall a v. (CommonContext a v, Num a) => v a -> [Test]
|
||||
testNumFunctions _ = $(testProperties ['prop_sum, 'prop_product])
|
||||
where
|
||||
prop_sum :: P (v a -> a) = V.sum `eq` sum
|
||||
prop_product :: P (v a -> a) = V.product `eq` product
|
||||
|
||||
testNestedVectorFunctions :: forall a v. (CommonContext a v) => v a -> [Test]
|
||||
testNestedVectorFunctions _ = $(testProperties [])
|
||||
where
|
||||
-- Prelude
|
||||
--prop_concat = (V.concat :: [v a] -> v a) `eq1` concat
|
||||
|
||||
-- Data.List
|
||||
--prop_transpose = V.transpose `eq1` (transpose :: [v a] -> [v a])
|
||||
--prop_group = V.group `eq1` (group :: v a -> [v a])
|
||||
--prop_inits = V.inits `eq1` (inits :: v a -> [v a])
|
||||
--prop_tails = V.tails `eq1` (tails :: v a -> [v a])
|
||||
|
||||
testGeneralBoxedVector :: forall a. (CommonContext a Data.Vector.Vector, Ord a) => Data.Vector.Vector a -> [Test]
|
||||
testGeneralBoxedVector dummy = concatMap ($ dummy) [
|
||||
testSanity,
|
||||
testPolymorphicFunctions,
|
||||
testOrdFunctions,
|
||||
testTuplyFunctions,
|
||||
testNestedVectorFunctions,
|
||||
testMonoidFunctions,
|
||||
testFunctorFunctions,
|
||||
testMonadFunctions,
|
||||
testApplicativeFunctions,
|
||||
testAlternativeFunctions
|
||||
]
|
||||
|
||||
testBoolBoxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralBoxedVector
|
||||
, testBoolFunctions
|
||||
]
|
||||
|
||||
testNumericBoxedVector :: forall a. (CommonContext a Data.Vector.Vector, Ord a, Num a, Enum a, Random a) => Data.Vector.Vector a -> [Test]
|
||||
testNumericBoxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralBoxedVector
|
||||
, testNumFunctions
|
||||
, testEnumFunctions
|
||||
]
|
||||
|
||||
|
||||
testGeneralPrimitiveVector :: forall a. (CommonContext a Data.Vector.Primitive.Vector, Data.Vector.Primitive.Prim a, Ord a) => Data.Vector.Primitive.Vector a -> [Test]
|
||||
testGeneralPrimitiveVector dummy = concatMap ($ dummy) [
|
||||
testSanity,
|
||||
testPolymorphicFunctions,
|
||||
testOrdFunctions,
|
||||
testMonoidFunctions
|
||||
]
|
||||
|
||||
testNumericPrimitiveVector :: forall a. (CommonContext a Data.Vector.Primitive.Vector, Data.Vector.Primitive.Prim a, Ord a, Num a, Enum a, Random a) => Data.Vector.Primitive.Vector a -> [Test]
|
||||
testNumericPrimitiveVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralPrimitiveVector
|
||||
, testNumFunctions
|
||||
, testEnumFunctions
|
||||
]
|
||||
|
||||
|
||||
testGeneralStorableVector :: forall a. (CommonContext a Data.Vector.Storable.Vector, Data.Vector.Storable.Storable a, Ord a) => Data.Vector.Storable.Vector a -> [Test]
|
||||
testGeneralStorableVector dummy = concatMap ($ dummy) [
|
||||
testSanity,
|
||||
testPolymorphicFunctions,
|
||||
testOrdFunctions,
|
||||
testMonoidFunctions
|
||||
]
|
||||
|
||||
testNumericStorableVector :: forall a. (CommonContext a Data.Vector.Storable.Vector, Data.Vector.Storable.Storable a, Ord a, Num a, Enum a, Random a) => Data.Vector.Storable.Vector a -> [Test]
|
||||
testNumericStorableVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralStorableVector
|
||||
, testNumFunctions
|
||||
, testEnumFunctions
|
||||
]
|
||||
|
||||
|
||||
testGeneralUnboxedVector :: forall a. (CommonContext a Data.Vector.Unboxed.Vector, Data.Vector.Unboxed.Unbox a, Ord a) => Data.Vector.Unboxed.Vector a -> [Test]
|
||||
testGeneralUnboxedVector dummy = concatMap ($ dummy) [
|
||||
testSanity,
|
||||
testPolymorphicFunctions,
|
||||
testOrdFunctions,
|
||||
testMonoidFunctions
|
||||
]
|
||||
|
||||
testUnitUnboxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralUnboxedVector
|
||||
]
|
||||
|
||||
testBoolUnboxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralUnboxedVector
|
||||
, testBoolFunctions
|
||||
]
|
||||
|
||||
testNumericUnboxedVector :: forall a. (CommonContext a Data.Vector.Unboxed.Vector, Data.Vector.Unboxed.Unbox a, Ord a, Num a, Enum a, Random a) => Data.Vector.Unboxed.Vector a -> [Test]
|
||||
testNumericUnboxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralUnboxedVector
|
||||
, testNumFunctions
|
||||
, testEnumFunctions
|
||||
]
|
||||
|
||||
testTupleUnboxedVector :: forall a. (CommonContext a Data.Vector.Unboxed.Vector, Data.Vector.Unboxed.Unbox a, Ord a) => Data.Vector.Unboxed.Vector a -> [Test]
|
||||
testTupleUnboxedVector dummy = concatMap ($ dummy)
|
||||
[
|
||||
testGeneralUnboxedVector
|
||||
]
|
||||
|
||||
tests = [
|
||||
testGroup "Data.Vector.Vector (Bool)" (testBoolBoxedVector (undefined :: Data.Vector.Vector Bool)),
|
||||
testGroup "Data.Vector.Vector (Int)" (testNumericBoxedVector (undefined :: Data.Vector.Vector Int)),
|
||||
|
||||
testGroup "Data.Vector.Primitive.Vector (Int)" (testNumericPrimitiveVector (undefined :: Data.Vector.Primitive.Vector Int)),
|
||||
testGroup "Data.Vector.Primitive.Vector (Double)" (testNumericPrimitiveVector (undefined :: Data.Vector.Primitive.Vector Double)),
|
||||
|
||||
testGroup "Data.Vector.Storable.Vector (Int)" (testNumericStorableVector (undefined :: Data.Vector.Storable.Vector Int)),
|
||||
testGroup "Data.Vector.Storable.Vector (Double)" (testNumericStorableVector (undefined :: Data.Vector.Storable.Vector Double)),
|
||||
|
||||
testGroup "Data.Vector.Unboxed.Vector ()" (testUnitUnboxedVector (undefined :: Data.Vector.Unboxed.Vector ())),
|
||||
testGroup "Data.Vector.Unboxed.Vector (Bool)" (testBoolUnboxedVector (undefined :: Data.Vector.Unboxed.Vector Bool)),
|
||||
testGroup "Data.Vector.Unboxed.Vector (Int)" (testNumericUnboxedVector (undefined :: Data.Vector.Unboxed.Vector Int)),
|
||||
testGroup "Data.Vector.Unboxed.Vector (Double)" (testNumericUnboxedVector (undefined :: Data.Vector.Unboxed.Vector Double)),
|
||||
testGroup "Data.Vector.Unboxed.Vector (Int,Bool)" (testTupleUnboxedVector (undefined :: Data.Vector.Unboxed.Vector (Int,Bool))),
|
||||
testGroup "Data.Vector.Unboxed.Vector (Int,Bool,Int)" (testTupleUnboxedVector (undefined :: Data.Vector.Unboxed.Vector (Int,Bool,Int)))
|
||||
|
||||
]
|
||||
48
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Vector/UnitTests.hs
vendored
Normal file
48
third_party/bazel/rules_haskell/examples/vector/tests/Tests/Vector/UnitTests.hs
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
module Tests.Vector.UnitTests (tests) where
|
||||
|
||||
import Control.Applicative as Applicative
|
||||
import qualified Data.Vector.Storable as Storable
|
||||
import Foreign.Ptr
|
||||
import Foreign.Storable
|
||||
import Text.Printf
|
||||
|
||||
import Test.Framework
|
||||
import Test.Framework.Providers.HUnit (testCase)
|
||||
import Test.HUnit (Assertion, assertBool)
|
||||
|
||||
newtype Aligned a = Aligned { getAligned :: a }
|
||||
|
||||
instance (Storable a) => Storable (Aligned a) where
|
||||
sizeOf _ = sizeOf (undefined :: a)
|
||||
alignment _ = 128
|
||||
peek ptr = Aligned Applicative.<$> peek (castPtr ptr)
|
||||
poke ptr = poke (castPtr ptr) . getAligned
|
||||
|
||||
checkAddressAlignment :: forall a. (Storable a) => Storable.Vector a -> Assertion
|
||||
checkAddressAlignment xs = Storable.unsafeWith xs $ \ptr -> do
|
||||
let ptr' = ptrToWordPtr ptr
|
||||
msg = printf "Expected pointer with alignment %d but got 0x%08x" (toInteger align) (toInteger ptr')
|
||||
align :: WordPtr
|
||||
align = fromIntegral $ alignment dummy
|
||||
assertBool msg $ (ptr' `mod` align) == 0
|
||||
where
|
||||
dummy :: a
|
||||
dummy = undefined
|
||||
|
||||
tests :: [Test]
|
||||
tests =
|
||||
[ testGroup "Data.Vector.Storable.Vector Alignment"
|
||||
[ testCase "Aligned Double" $
|
||||
checkAddressAlignment alignedDoubleVec
|
||||
, testCase "Aligned Int" $
|
||||
checkAddressAlignment alignedIntVec
|
||||
]
|
||||
]
|
||||
|
||||
alignedDoubleVec :: Storable.Vector (Aligned Double)
|
||||
alignedDoubleVec = Storable.fromList $ map Aligned [1, 2, 3, 4, 5]
|
||||
|
||||
alignedIntVec :: Storable.Vector (Aligned Int)
|
||||
alignedIntVec = Storable.fromList $ map Aligned [1, 2, 3, 4, 5]
|
||||
350
third_party/bazel/rules_haskell/examples/vector/tests/Utilities.hs
vendored
Normal file
350
third_party/bazel/rules_haskell/examples/vector/tests/Utilities.hs
vendored
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
{-# LANGUAGE FlexibleInstances, GADTs #-}
|
||||
module Utilities where
|
||||
|
||||
import Test.QuickCheck
|
||||
|
||||
import qualified Data.Vector as DV
|
||||
import qualified Data.Vector.Generic as DVG
|
||||
import qualified Data.Vector.Primitive as DVP
|
||||
import qualified Data.Vector.Storable as DVS
|
||||
import qualified Data.Vector.Unboxed as DVU
|
||||
import qualified Data.Vector.Fusion.Bundle as S
|
||||
|
||||
import Control.Monad (foldM, foldM_, zipWithM, zipWithM_)
|
||||
import Control.Monad.Trans.Writer
|
||||
import Data.Function (on)
|
||||
import Data.Functor.Identity
|
||||
import Data.List ( sortBy )
|
||||
import Data.Monoid
|
||||
import Data.Maybe (catMaybes)
|
||||
|
||||
instance Show a => Show (S.Bundle v a) where
|
||||
show s = "Data.Vector.Fusion.Bundle.fromList " ++ show (S.toList s)
|
||||
|
||||
|
||||
instance Arbitrary a => Arbitrary (DV.Vector a) where
|
||||
arbitrary = fmap DV.fromList arbitrary
|
||||
|
||||
instance CoArbitrary a => CoArbitrary (DV.Vector a) where
|
||||
coarbitrary = coarbitrary . DV.toList
|
||||
|
||||
instance (Arbitrary a, DVP.Prim a) => Arbitrary (DVP.Vector a) where
|
||||
arbitrary = fmap DVP.fromList arbitrary
|
||||
|
||||
instance (CoArbitrary a, DVP.Prim a) => CoArbitrary (DVP.Vector a) where
|
||||
coarbitrary = coarbitrary . DVP.toList
|
||||
|
||||
instance (Arbitrary a, DVS.Storable a) => Arbitrary (DVS.Vector a) where
|
||||
arbitrary = fmap DVS.fromList arbitrary
|
||||
|
||||
instance (CoArbitrary a, DVS.Storable a) => CoArbitrary (DVS.Vector a) where
|
||||
coarbitrary = coarbitrary . DVS.toList
|
||||
|
||||
instance (Arbitrary a, DVU.Unbox a) => Arbitrary (DVU.Vector a) where
|
||||
arbitrary = fmap DVU.fromList arbitrary
|
||||
|
||||
instance (CoArbitrary a, DVU.Unbox a) => CoArbitrary (DVU.Vector a) where
|
||||
coarbitrary = coarbitrary . DVU.toList
|
||||
|
||||
instance Arbitrary a => Arbitrary (S.Bundle v a) where
|
||||
arbitrary = fmap S.fromList arbitrary
|
||||
|
||||
instance CoArbitrary a => CoArbitrary (S.Bundle v a) where
|
||||
coarbitrary = coarbitrary . S.toList
|
||||
|
||||
instance (Arbitrary a, Arbitrary b) => Arbitrary (Writer a b) where
|
||||
arbitrary = do b <- arbitrary
|
||||
a <- arbitrary
|
||||
return $ writer (b,a)
|
||||
|
||||
instance CoArbitrary a => CoArbitrary (Writer a ()) where
|
||||
coarbitrary = coarbitrary . runWriter
|
||||
|
||||
class (Testable (EqTest a), Conclusion (EqTest a)) => TestData a where
|
||||
type Model a
|
||||
model :: a -> Model a
|
||||
unmodel :: Model a -> a
|
||||
|
||||
type EqTest a
|
||||
equal :: a -> a -> EqTest a
|
||||
|
||||
instance Eq a => TestData (S.Bundle v a) where
|
||||
type Model (S.Bundle v a) = [a]
|
||||
model = S.toList
|
||||
unmodel = S.fromList
|
||||
|
||||
type EqTest (S.Bundle v a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance Eq a => TestData (DV.Vector a) where
|
||||
type Model (DV.Vector a) = [a]
|
||||
model = DV.toList
|
||||
unmodel = DV.fromList
|
||||
|
||||
type EqTest (DV.Vector a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, DVP.Prim a) => TestData (DVP.Vector a) where
|
||||
type Model (DVP.Vector a) = [a]
|
||||
model = DVP.toList
|
||||
unmodel = DVP.fromList
|
||||
|
||||
type EqTest (DVP.Vector a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, DVS.Storable a) => TestData (DVS.Vector a) where
|
||||
type Model (DVS.Vector a) = [a]
|
||||
model = DVS.toList
|
||||
unmodel = DVS.fromList
|
||||
|
||||
type EqTest (DVS.Vector a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, DVU.Unbox a) => TestData (DVU.Vector a) where
|
||||
type Model (DVU.Vector a) = [a]
|
||||
model = DVU.toList
|
||||
unmodel = DVU.fromList
|
||||
|
||||
type EqTest (DVU.Vector a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
#define id_TestData(ty) \
|
||||
instance TestData ty where { \
|
||||
type Model ty = ty; \
|
||||
model = id; \
|
||||
unmodel = id; \
|
||||
\
|
||||
type EqTest ty = Property; \
|
||||
equal x y = property (x == y) }
|
||||
|
||||
id_TestData(())
|
||||
id_TestData(Bool)
|
||||
id_TestData(Int)
|
||||
id_TestData(Float)
|
||||
id_TestData(Double)
|
||||
id_TestData(Ordering)
|
||||
|
||||
-- Functorish models
|
||||
-- All of these need UndecidableInstances although they are actually well founded. Oh well.
|
||||
instance (Eq a, TestData a) => TestData (Maybe a) where
|
||||
type Model (Maybe a) = Maybe (Model a)
|
||||
model = fmap model
|
||||
unmodel = fmap unmodel
|
||||
|
||||
type EqTest (Maybe a) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, TestData a) => TestData [a] where
|
||||
type Model [a] = [Model a]
|
||||
model = fmap model
|
||||
unmodel = fmap unmodel
|
||||
|
||||
type EqTest [a] = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, TestData a) => TestData (Identity a) where
|
||||
type Model (Identity a) = Identity (Model a)
|
||||
model = fmap model
|
||||
unmodel = fmap unmodel
|
||||
|
||||
type EqTest (Identity a) = Property
|
||||
equal = (property .) . on (==) runIdentity
|
||||
|
||||
instance (Eq a, TestData a, Eq b, TestData b, Monoid a) => TestData (Writer a b) where
|
||||
type Model (Writer a b) = Writer (Model a) (Model b)
|
||||
model = mapWriter model
|
||||
unmodel = mapWriter unmodel
|
||||
|
||||
type EqTest (Writer a b) = Property
|
||||
equal = (property .) . on (==) runWriter
|
||||
|
||||
instance (Eq a, Eq b, TestData a, TestData b) => TestData (a,b) where
|
||||
type Model (a,b) = (Model a, Model b)
|
||||
model (a,b) = (model a, model b)
|
||||
unmodel (a,b) = (unmodel a, unmodel b)
|
||||
|
||||
type EqTest (a,b) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Eq a, Eq b, Eq c, TestData a, TestData b, TestData c) => TestData (a,b,c) where
|
||||
type Model (a,b,c) = (Model a, Model b, Model c)
|
||||
model (a,b,c) = (model a, model b, model c)
|
||||
unmodel (a,b,c) = (unmodel a, unmodel b, unmodel c)
|
||||
|
||||
type EqTest (a,b,c) = Property
|
||||
equal x y = property (x == y)
|
||||
|
||||
instance (Arbitrary a, Show a, TestData a, TestData b) => TestData (a -> b) where
|
||||
type Model (a -> b) = Model a -> Model b
|
||||
model f = model . f . unmodel
|
||||
unmodel f = unmodel . f . model
|
||||
|
||||
type EqTest (a -> b) = a -> EqTest b
|
||||
equal f g x = equal (f x) (g x)
|
||||
|
||||
newtype P a = P { unP :: EqTest a }
|
||||
|
||||
instance TestData a => Testable (P a) where
|
||||
property (P a) = property a
|
||||
|
||||
infix 4 `eq`
|
||||
eq :: TestData a => a -> Model a -> P a
|
||||
eq x y = P (equal x (unmodel y))
|
||||
|
||||
class Conclusion p where
|
||||
type Predicate p
|
||||
|
||||
predicate :: Predicate p -> p -> p
|
||||
|
||||
instance Conclusion Property where
|
||||
type Predicate Property = Bool
|
||||
|
||||
predicate = (==>)
|
||||
|
||||
instance Conclusion p => Conclusion (a -> p) where
|
||||
type Predicate (a -> p) = a -> Predicate p
|
||||
|
||||
predicate f p = \x -> predicate (f x) (p x)
|
||||
|
||||
infixr 0 ===>
|
||||
(===>) :: TestData a => Predicate (EqTest a) -> P a -> P a
|
||||
p ===> P a = P (predicate p a)
|
||||
|
||||
notNull2 _ xs = not $ DVG.null xs
|
||||
notNullS2 _ s = not $ S.null s
|
||||
|
||||
-- Generators
|
||||
index_value_pairs :: Arbitrary a => Int -> Gen [(Int,a)]
|
||||
index_value_pairs 0 = return []
|
||||
index_value_pairs m = sized $ \n ->
|
||||
do
|
||||
len <- choose (0,n)
|
||||
is <- sequence [choose (0,m-1) | i <- [1..len]]
|
||||
xs <- vector len
|
||||
return $ zip is xs
|
||||
|
||||
indices :: Int -> Gen [Int]
|
||||
indices 0 = return []
|
||||
indices m = sized $ \n ->
|
||||
do
|
||||
len <- choose (0,n)
|
||||
sequence [choose (0,m-1) | i <- [1..len]]
|
||||
|
||||
|
||||
-- Additional list functions
|
||||
singleton x = [x]
|
||||
snoc xs x = xs ++ [x]
|
||||
generate n f = [f i | i <- [0 .. n-1]]
|
||||
slice i n xs = take n (drop i xs)
|
||||
backpermute xs is = map (xs!!) is
|
||||
prescanl f z = init . scanl f z
|
||||
postscanl f z = tail . scanl f z
|
||||
prescanr f z = tail . scanr f z
|
||||
postscanr f z = init . scanr f z
|
||||
|
||||
accum :: (a -> b -> a) -> [a] -> [(Int,b)] -> [a]
|
||||
accum f xs ps = go xs ps' 0
|
||||
where
|
||||
ps' = sortBy (\p q -> compare (fst p) (fst q)) ps
|
||||
|
||||
go (x:xs) ((i,y) : ps) j
|
||||
| i == j = go (f x y : xs) ps j
|
||||
go (x:xs) ps j = x : go xs ps (j+1)
|
||||
go [] _ _ = []
|
||||
|
||||
(//) :: [a] -> [(Int, a)] -> [a]
|
||||
xs // ps = go xs ps' 0
|
||||
where
|
||||
ps' = sortBy (\p q -> compare (fst p) (fst q)) ps
|
||||
|
||||
go (x:xs) ((i,y) : ps) j
|
||||
| i == j = go (y:xs) ps j
|
||||
go (x:xs) ps j = x : go xs ps (j+1)
|
||||
go [] _ _ = []
|
||||
|
||||
|
||||
withIndexFirst m f = m (uncurry f) . zip [0..]
|
||||
|
||||
imap :: (Int -> a -> a) -> [a] -> [a]
|
||||
imap = withIndexFirst map
|
||||
|
||||
imapM :: Monad m => (Int -> a -> m a) -> [a] -> m [a]
|
||||
imapM = withIndexFirst mapM
|
||||
|
||||
imapM_ :: Monad m => (Int -> a -> m b) -> [a] -> m ()
|
||||
imapM_ = withIndexFirst mapM_
|
||||
|
||||
izipWith :: (Int -> a -> a -> a) -> [a] -> [a] -> [a]
|
||||
izipWith = withIndexFirst zipWith
|
||||
|
||||
izipWithM :: Monad m => (Int -> a -> a -> m a) -> [a] -> [a] -> m [a]
|
||||
izipWithM = withIndexFirst zipWithM
|
||||
|
||||
izipWithM_ :: Monad m => (Int -> a -> a -> m b) -> [a] -> [a] -> m ()
|
||||
izipWithM_ = withIndexFirst zipWithM_
|
||||
|
||||
izipWith3 :: (Int -> a -> a -> a -> a) -> [a] -> [a] -> [a] -> [a]
|
||||
izipWith3 = withIndexFirst zipWith3
|
||||
|
||||
ifilter :: (Int -> a -> Bool) -> [a] -> [a]
|
||||
ifilter f = map snd . withIndexFirst filter f
|
||||
|
||||
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
|
||||
mapMaybe f = catMaybes . map f
|
||||
|
||||
imapMaybe :: (Int -> a -> Maybe b) -> [a] -> [b]
|
||||
imapMaybe f = catMaybes . withIndexFirst map f
|
||||
|
||||
indexedLeftFold fld f z = fld (uncurry . f) z . zip [0..]
|
||||
|
||||
ifoldl :: (a -> Int -> a -> a) -> a -> [a] -> a
|
||||
ifoldl = indexedLeftFold foldl
|
||||
|
||||
iscanl :: (Int -> a -> b -> a) -> a -> [b] -> [a]
|
||||
iscanl f z = scanl (\a (i, b) -> f i a b) z . zip [0..]
|
||||
|
||||
iscanr :: (Int -> a -> b -> b) -> b -> [a] -> [b]
|
||||
iscanr f z = scanr (uncurry f) z . zip [0..]
|
||||
|
||||
ifoldr :: (Int -> a -> b -> b) -> b -> [a] -> b
|
||||
ifoldr f z = foldr (uncurry f) z . zip [0..]
|
||||
|
||||
ifoldM :: Monad m => (a -> Int -> a -> m a) -> a -> [a] -> m a
|
||||
ifoldM = indexedLeftFold foldM
|
||||
|
||||
ifoldM_ :: Monad m => (b -> Int -> a -> m b) -> b -> [a] -> m ()
|
||||
ifoldM_ = indexedLeftFold foldM_
|
||||
|
||||
minIndex :: Ord a => [a] -> Int
|
||||
minIndex = fst . foldr1 imin . zip [0..]
|
||||
where
|
||||
imin (i,x) (j,y) | x <= y = (i,x)
|
||||
| otherwise = (j,y)
|
||||
|
||||
maxIndex :: Ord a => [a] -> Int
|
||||
maxIndex = fst . foldr1 imax . zip [0..]
|
||||
where
|
||||
imax (i,x) (j,y) | x >= y = (i,x)
|
||||
| otherwise = (j,y)
|
||||
|
||||
iterateNM :: Monad m => Int -> (a -> m a) -> a -> m [a]
|
||||
iterateNM n f x
|
||||
| n <= 0 = return []
|
||||
| n == 1 = return [x]
|
||||
| otherwise = do x' <- f x
|
||||
xs <- iterateNM (n-1) f x'
|
||||
return (x : xs)
|
||||
|
||||
unfoldrM :: Monad m => (b -> m (Maybe (a,b))) -> b -> m [a]
|
||||
unfoldrM step b0 = do
|
||||
r <- step b0
|
||||
case r of
|
||||
Nothing -> return []
|
||||
Just (a,b) -> do as <- unfoldrM step b
|
||||
return (a : as)
|
||||
|
||||
|
||||
limitUnfolds f (theirs, ours)
|
||||
| ours >= 0
|
||||
, Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1))
|
||||
| otherwise = Nothing
|
||||
Loading…
Add table
Add a link
Reference in a new issue