packages feed

unpacked-either-0.1.0.0: test/Main.hs

{-# LANGUAGE KindSignatures #-}

module Main (main) where

import Prelude hiding (Either(..), either)

import Control.Applicative
import Control.Monad (liftM)
import Data.Functor.Classes
import Data.Either.Unpacked (Either(Left,Right), left, right)
import Data.Proxy (Proxy(..))
import Data.Semigroup (Semigroup((<>)))
import Test.QuickCheck.Classes
import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen

main :: IO ()
main = lawsCheckMany myClassTests

myClassTests :: [(String, [Laws])]
myClassTests =
  [ ("Ground types", myLaws eitherProxy)
  , ("Higher-kinded types", myLaws1 eitherProxy1)
  ]

myLaws
  :: (Arbitrary a, Eq a, Ord a, Show a, Read a)
  => Proxy a -> [Laws]
myLaws p =
  [ eqLaws p
  , ordLaws p
  , showReadLaws p
  ]

myLaws1
  :: (Arbitrary1 a, Monad a, Functor a, Applicative a, Foldable a, Traversable a, Eq1 a, Show1 a)
  => Proxy a -> [Laws]
myLaws1 p =
  [ monadLaws p
  , functorLaws p
  , applicativeLaws p
  , foldableLaws p
  , traversableLaws p
  ]

eitherProxy2 :: Proxy Either
eitherProxy2 = Proxy

eitherProxy1 :: Proxy (Either Int)
eitherProxy1 = Proxy

eitherProxy  :: Proxy (Either Int Int)
eitherProxy  = Proxy

instance Semigroup Int where
  (<>) = (+)

instance Monoid Int where
  mempty = 0
  mappend = (+)

instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b) where
  arbitrary = arbitrary2
  shrink = shrink2

instance Arbitrary2 Either where
  liftArbitrary2 arbA arbB = oneof [liftM Left arbA, liftM Right arbB]

  liftShrink2 shrA _ (Left x)  = [ Left  x' | x' <- shrA x ]
  liftShrink2 _ shrB (Right y) = [ Right y' | y' <- shrB y ]

instance Arbitrary a => Arbitrary1 (Either a) where
  liftArbitrary = liftArbitrary2 arbitrary
  liftShrink = liftShrink2 shrink