1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE StandaloneDeriving #-}
----------------------------------------------------------------------
-- |
-- Copyright : (c) Edward Kmett 2011-2014
-- License : BSD3
--
-- Maintainer : ekmett@gmail.com
-- Stability : experimental
--
-- Tests for generically derived 'Representable' instances.
----------------------------------------------------------------------
module GenericsSpec (main, spec) where
import Data.Distributive (Distributive(..))
import Data.Functor.Rep (Representable(..), WrappedRep(..))
import GHC.Generics hiding (Rep)
import Test.Hspec
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
describe "Id" $
itIndexes "idExample" "idRep" idExample idRep 42
describe "Stream" $ do
let streamIndexes :: String -> Rep Stream -> Int -> Spec
streamIndexes repNum = itIndexes "streamExample" ("streamRep" ++ repNum) streamExample
streamIndexes "1" streamRep1 0
streamIndexes "2" streamRep2 1
streamIndexes "3" streamRep3 2
describe "PolyRec" $ do
let polyRecIndexes :: String -> Rep PolyRec -> Int -> Spec
polyRecIndexes repNum = itIndexes "polyRecExample" ("polyRecRep" ++ repNum)
polyRecExample
polyRecIndexes "1" polyRecRep1 1
polyRecIndexes "2" polyRecRep2 2
polyRecIndexes "3" polyRecRep3 0
itIndexes :: (Eq a, Representable f, Show a)
=> String -> String -> f a -> Rep f -> a -> Spec
itIndexes exampleStr repStr exampleVal rep res =
it ("index " ++ exampleStr ++ " " ++ repStr ++ " = " ++ show res) $
index exampleVal rep `shouldBe` res
-------------------------------------------------------------------------------
newtype Id a = Id { runId :: a }
deriving Functor
instance Distributive Id where
collect f = Id . fmap (runId . f)
distribute = Id . fmap runId
instance Representable Id
-- type Rep Id = ()
idExample :: Id Int
idExample = Id 42
idRep :: Rep Id
idRep = ()
data Stream a = (:>) { shead :: a, stail :: Stream a }
deriving Functor
instance Distributive Stream where
distribute w = fmap shead w :> distribute (fmap stail w)
instance Representable Stream
-- type Rep Stream = Either () (WrappedRep Stream)
streamExample :: Stream Int
streamExample = let s = 0 :> fmap (+1) s in s
streamRep1, streamRep2, streamRep3 :: Rep Stream
streamRep1 = Left ()
streamRep2 = Right $ WrapRep $ Left ()
streamRep3 = Right $ WrapRep $ Right $ WrapRep $ Left ()
data PolyRec a = PolyRec (Id (PolyRec a)) a
deriving Functor
instance Distributive PolyRec where
distribute fpa = PolyRec (Id $ distribute fpa) (fmap (\(PolyRec _ a) -> a) fpa)
instance Representable PolyRec
-- type Rep PolyRec = Either (WrappedRep Id, WrappedRep PolyRec) ()
polyRecExample :: PolyRec Int
polyRecExample = let p = PolyRec (Id (fmap (+1) p)) 0 in p
polyRecRep1, polyRecRep2, polyRecRep3 :: Rep PolyRec
polyRecRep1 = Left (WrapRep (), WrapRep $ Right ())
polyRecRep2 = Left (WrapRep (), WrapRep $ Left (WrapRep (), WrapRep $ Right ()))
polyRecRep3 = Right ()
deriving instance Generic1 Id
deriving instance Generic1 Stream
deriving instance Generic1 PolyRec
|