Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.05 KB | None | 0 0
  1. {-# LANGUAGE FlexibleInstances #-}
  2. {-# LANGUAGE FlexibleContexts #-}
  3. {-# LANGUAGE TypeApplications #-}
  4. {-# LANGUAGE ScopedTypeVariables #-}
  5. {-# LANGUAGE GADTs #-}
  6. module Generators where
  7.  
  8. import Test.QuickCheck
  9. import Data.Proxy
  10. import Data.Coerce
  11.  
  12. data Expr a where
  13. Const :: a -> Expr a
  14. Map :: Show b => Expr b -> (b -> a) -> Expr a
  15. Filter :: Expr a -> (a -> Bool) -> Expr a
  16. Join :: (Show a, Show b) => Expr a -> Expr b -> Expr (a, b)
  17.  
  18.  
  19. instance Show a => Show (Expr a) where
  20. show (Const a) = "(Const " ++ show a ++ ")"
  21. show (Map e _) = "(Map f " ++ show e ++ ")"
  22. show (Filter e _) = "(Filter p " ++ show e ++ ")"
  23. show (Join l r) = "(Join " ++ show l ++ " " ++ show r ++ ")"
  24.  
  25.  
  26.  
  27. instance (Arbitrary a, CoArbitrary a, Show a) => Arbitrary (Expr a) where
  28. arbitrary = oneof (generators (Proxy @(Expr a)))
  29.  
  30. newtype TupledExpr a = Tupled {
  31. unTupled :: (Expr a)
  32. }
  33. instance (Arbitrary a, CoArbitrary a,
  34. Arbitrary b, CoArbitrary b,
  35. Show a, Show b) =>
  36. Arbitrary (TupledExpr (a, b)) where
  37. arbitrary = coerce
  38. $ oneof (joinGen : generators (Proxy @(TupledExpr (a,b))))
  39.  
  40.  
  41. generators :: forall b a. (Coercible b (Expr a), Arbitrary b, CoArbitrary a, Arbitrary a, Show a) => Proxy b -> [Gen (Expr a)]
  42. generators t = [
  43. constGen
  44. , filterGen t
  45. , mapGen t
  46. , mapGen (Proxy @(TupledExpr (a, Bool)))
  47. , mapGen (Proxy @(TupledExpr ((a, Bool), a)))
  48. ]
  49.  
  50. constGen :: Arbitrary a => Gen (Expr a)
  51. constGen = Const <$> arbitrary
  52.  
  53. filterGen :: forall b a. (Coercible b (Expr a), Arbitrary b, CoArbitrary a) => Proxy b -> Gen (Expr a)
  54. filterGen _ = do
  55. e <- coerce $ arbitrary @b
  56. p <- arbitrary @(a -> Bool)
  57. pure (Filter e p)
  58.  
  59. mapGen :: forall b x a. (Coercible b (Expr x), Arbitrary b, CoArbitrary x, Arbitrary a, Show x) => Proxy b -> Gen (Expr a)
  60. mapGen _ = do
  61. arg <- coerce $ arbitrary @b
  62. f <- arbitrary @(x -> a)
  63. pure (Map arg f)
  64.  
  65. joinGen :: forall a b. (Arbitrary (Expr a), Arbitrary (Expr b), Show b, Show a) => Gen (Expr (a,b))
  66. joinGen = do
  67. left <- arbitrary @(Expr a)
  68. right <- arbitrary @(Expr b)
  69. pure (Join left right)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement