{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE UndecidableInstances #-} import Prelude import Test.HUnit import qualified Data.Vector.Unboxing as V import qualified Data.Vector.Unboxed import Data.Monoid (Sum(..)) import Data.MonoTraversable (ofold) --- import TestTypeErrors import Foo (Foo,mkFoo) import Generic testInt = TestCase $ do let v = V.fromList [2,-5,42] :: V.Vector Int w = Data.Vector.Unboxed.fromList [2,-5,42] :: Data.Vector.Unboxed.Vector Int assertEqual "to unboxed" w (V.toUnboxedVector v) assertEqual "from unboxed" v (V.fromUnboxedVector w) newtype IntMod17 = IntMod17 Int deriving (Eq,Show) -- deriving newtype VF.Unboxable instance V.Unboxable IntMod17 where type Rep IntMod17 = Int instance Num IntMod17 where IntMod17 x + IntMod17 y = IntMod17 ((x + y) `rem` 17) IntMod17 x - IntMod17 y = IntMod17 ((x - y) `mod` 17) IntMod17 x * IntMod17 y = IntMod17 ((x * y) `rem` 17) negate (IntMod17 x) = IntMod17 (negate x `mod` 17) fromInteger x = IntMod17 (fromIntegral (x `mod` 17)) abs = undefined; signum = undefined testIntMod17 = TestCase $ do let v = V.fromList [-3,-2,-1,0,1,2,3,4,5] :: V.Vector IntMod17 assertEqual "construction" (V.fromList [14,15,16,0,1,2,3,4,5]) v assertEqual "sum" 9 (V.sum v) -- not 60 assertEqual "coercion" (V.fromList [14,15,16,0,1,2,3,4,5] :: V.Vector Int) (V.coerceVector v) -- this is possible because the constructor of IntMod17 is visible here let vSum = V.coerceVector v :: V.Vector (Sum IntMod17) assertEqual "coercion and sum" (Sum 9) (ofold vSum) newtype Baz = Baz Foo deriving (Eq,Show,V.Unboxable) testBaz = TestCase $ do let foo :: V.Vector Foo foo = V.singleton mkFoo baz :: V.Vector Baz baz = V.singleton (Baz mkFoo) assertEqual "construction" (Baz mkFoo) (V.head baz) assertEqual "map 1" baz (V.map Baz foo) assertEqual "map 2" foo (V.map (\(Baz x) -> x) baz) assertEqual "coercion" baz (V.coerceVector foo) -- We can make an unboxed vector of Foo, even though we don't have 'Coercible Int Foo' in scope. testAbstractType = TestCase $ do let v = V.singleton mkFoo :: V.Vector Foo assertEqual "Foo" mkFoo (V.head v) assertEqual "coercion" mkFoo (getSum $ V.head (V.coerceVector v :: V.Vector (Sum Foo))) tests = TestList [TestLabel "Basic features" testIntMod17 ,TestLabel "Conversion with Data.Vector.Unboxed" testInt ,TestLabel "Test with abstract type" testAbstractType ,TestLabel "Check for type errors" testTypeErrors ,TestLabel "Test with generic 1" testComplexDouble ,TestLabel "Test with generic 2" testBar ,TestLabel "Test with GND" testBaz ] main = runTestTT tests