packages feed

type-spec 0.1.0.0 → 0.2.0.0

raw patch · 15 files changed

+627/−219 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Test.TypeSpec.Group: type (-*) expectation1 expectation2 = expectation1 -/- expectation2
- Test.TypeSpec.Internal.Apply: type TyFunData a b = TyFun a b -> Type
+ Test.TypeSpec: type Not = ShouldBeTrue
+ Test.TypeSpec: type That = ShouldBeTrue
- Test.TypeSpec.Internal.Apply: data Const' :: a -> (TyFunData b a)
+ Test.TypeSpec.Internal.Apply: data Const' :: a -> (b ~> a)
- Test.TypeSpec.Internal.Apply: data Const'' :: TyFunData a (TyFunData b a)
+ Test.TypeSpec.Internal.Apply: data Const'' :: a ~> (b ~> a)

Files

+ .travis.yml view
@@ -0,0 +1,24 @@+language: c++sudo: false+cache:+  directories:+  - $HOME/.stack/++matrix:+  include:+    - env: CABALVER=1.22 GHCVER=8.0.1+      addons: {apt: {packages: [cabal-install-1.22,ghc-8.0.1],sources: [hvr-ghc]}}++before_install:+  - mkdir -p ~/.local/bin+  - export PATH=~/.local/bin:$PATH+  - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar -xzO --wildcards '*/stack' > ~/.local/bin/stack+  - chmod a+x ~/.local/bin/stack++install:+  - stack -j 2 setup --no-terminal --resolver nightly+  - stack -j 2 build --only-snapshot --no-terminal++script:+  - stack -j 2 test --no-terminal
+ README.md view
@@ -0,0 +1,110 @@++[![Build Status](https://travis-ci.org/sheyll/type-spec.svg?branch=master)](https://travis-ci.org/sheyll/type-spec)++[![Hackage](https://img.shields.io/badge/type-spec-green.svg?style=flat)](http://hackage.haskell.org/package/type-spec)+++# A tiny EDSL to write type-level-unit tests.+++A small example:++    import Test.TypeSpec++    main :: IO ()+    main = print spec0++    spec :: Expect (Int `Isn't` Bool)+    spec = Valid++This will output:++    Valid:+         • Type:  Int+           differs from:  Bool++Using the operators from _TypeSpecCrazy_:++    specCrazy ::++        "Higher kinded assertions"+       ###########################++       "ShouldBe accepts types of kind * -> *"+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++           ShouldBe  Maybe Maybe+        -* ShouldBe  []    []+        -* ShouldBe  (->)  (->)++    specCrazy = Valid+    main = print specCrazy++The output:++    Valid:+         Higher kinded assertions+           ShouldBe accepts types of kind * -> *+             • Types are equal+             • Types are equal+             • Types are equal++If you like Lisp, this might be for you:++    type ALot = 1000++    specAliases ::+      (Explain "There are a variety aliases for the basic combinators."+        (Context "Basic Combinators"+          (Describe "Context"+            (It "labels expectations using 'It'"+              (Describe "Describe"+                (It's "an alias for It, just like They"+                  (It's "time for the first assertion"+                    (1000 `Is` ALot))))))))+    specAliases = Valid++    main = print specAliases++This will output:++    Valid:+         There are a variety aliases for the basic combinators.+           Basic Combinators+             Context+               Labels expectations using 'It'+                 Describe+                   is an alias for It, just like They+                     is time for the first assertion+                       • Types are equal++The key feature is that the compiler checks the assertions and expectations made+in a 'TypeSpec' and right away rejects invalid types.++When compiling this example:++    specFailing ::+        TypeSpec+            (It "counts the number of elements in a tuple"+                (Count ((),(),()) `ShouldBe` 4))+    specFailing = Valid++    type family Count a :: Nat where+      Count (a,b) = 2+      Count (a,b,c) = 3+      Count (a,b,c,d) = 4++The compiler complains:++    error:+       • counts the number of elements in a tuple+             Expected type: 3+             Actual type:   4+       • In the expression: Valid+         In an equation for ‘specFailing’: specFailing = Valid+++After all, with `TypeError` GHC is quite a test-runner.++If you accept to defer type checking and have invalid specs checked during test execution, use+(should-not-typecheck)[https://github.com/CRogers/should-not-typecheck].
examples/Main.hs view
@@ -1,7 +1,6 @@ -- | Some examples for 'Test.TypeSpec' module Main where -import Data.Kind import GHC.TypeLits import Test.TypeSpecCrazy @@ -15,6 +14,7 @@   print spec1   print specCrazy   print specInvalidCrazy+  print specCrazyMoreNested  -- * TypeSpec Examples @@ -155,3 +155,37 @@  specInvalidCrazy :: SpecInvalidCrazy specInvalidCrazy = Invalid+++specCrazyMoreNested ::++  "Title"+  ######++    "Top-level "+    ~~~~~~~~~~~~++         "Nested:"+         ~~~~~~~~~+         Int `Is` Int+                            -*-+         Int `Is` Int+                            -*-+         Int `Is` Int++                            -/-++    "Top-level "+    ~~~~~~~~~~~~++         "Nested:"+         ~~~~~~~~~+         Int `Is` Int+                            -*-+             "Nested:"+             ~~~~~~~~~+             Int `Is` Int+                                -*-+             Int `Is` Int++specCrazyMoreNested = Valid
src/Test/TypeSpec.hs view
@@ -1,37 +1,102 @@--- | A tiny EDSL to write type-level-unit tests.+{-|+Module      : Test.TypeSpec+Description : Type-Level eDSL for Type-Unit-Tests+Copyright   : (c) Sven Heyll, 2016+License     : BSD-3+Maintainer  : sven.heyll@gmail.com+Stability   : experimental++A tiny EDSL to write type-level-unit tests.++A simple example:++> specHelloWorld :: Expect (Int `Isn't` Bool)+> specHelloWorld = Valid++We can also /expect/ a bit more using lists and tuples:++> specGrouped+>   :: Expect '[ Int  `Isn't` Bool+>              , Int  `Is`    Int+>              , Bool `Is`    Bool  `ButNot`  String+>              ]+> specGrouped = Valid++The expectations are /executed/ by the compiler when solving the constraints of+'TypeSpec's constructors.++A 'TypeSpec' also has a 'Show' instance, which can be used in real unit tests+to print the expectations.++ This module contains mainly re-exports of.++ * "Test.TypeSpec.Core"++ * "Test.TypeSpec.Group"++ * "Test.TypeSpec.Label"++ * "Test.TypeSpec.ShouldBe"++-} module Test.TypeSpec-  ( type Expect-  , type Explain-  , type It's-  , type IsTheSameAs-  , type Is-  , type TheseAreEqual-  , type IsNot-  , type Isn't-  , type IsNotTheSameAs-  , type IsDifferentFrom-  , type TheseAreNotEqual-  , type IsTrue-  , type Therefore-  , type And-  , type IsFalse-  , type They-  , type Describe-  , type Context-  , module ReExport)+  (+  -- * 'TypeSpec' Aliases++  type Expect,+  type Explain,++  -- * 'ShouldBe' aliases++  type Is,+  type IsTheSameAs,+  type TheseAreEqual,++  -- * 'ShouldNotBe' aliases++  type IsNot,+  type Isn't,+  type IsNotTheSameAs,+  type IsDifferentFrom,+  type TheseAreNotEqual,++  -- * 'ShouldBeTrue' aliases++  type IsTrue,+  type And,+  type Therefore,+  type That,++  -- * 'ShouldBeFalse' aliases++  type IsFalse,+  type Not,++  -- * Labelling Aliases++  type They,+  type Describe,+  type Context,+  type It's,++  -- * Reexports++  module Test.TypeSpec.Core,+  module Test.TypeSpec.Group,+  module Test.TypeSpec.Label,+  module Test.TypeSpec.ShouldBe++  )   where -import Test.TypeSpec.Core as ReExport-import Test.TypeSpec.Group as ReExport-import Test.TypeSpec.Label as ReExport-import Test.TypeSpec.ShouldBe as ReExport+import Test.TypeSpec.Core+import Test.TypeSpec.Group+import Test.TypeSpec.Label+import Test.TypeSpec.ShouldBe  -- * 'TypeSpec' Aliases --- | An alias for 'TypeSpec'. type Expect = TypeSpec---- | Another alias for 'TypeSpec' (and also 'It') type Explain does this = TypeSpec (It does this)  -- * 'ShouldBe' aliases@@ -53,10 +118,12 @@ type IsTrue = ShouldBeTrue type And = ShouldBeTrue type Therefore = ShouldBeTrue+type That = ShouldBeTrue  -- * 'ShouldBeFalse' aliases  type IsFalse = ShouldBeFalse+type Not = ShouldBeTrue  -- * Labelling Aliases 
src/Test/TypeSpec/Core.hs view
@@ -1,7 +1,11 @@ -- | Core of the TypeSpec abstractions. Import to add custom instances. module Test.TypeSpec.Core-  ( TypeSpec (..)+  (+  -- * Core Data Type+   TypeSpec (..)+  -- * Expectations   , type EvalExpectation+  -- * Pretty Printing Support   , PrettyTypeSpec(..)   , prettyIndentation   , nest'@@ -16,8 +20,8 @@ import Test.TypeSpec.Internal.Result as ReExport import Text.PrettyPrint --- * Type Level Specifcations + -- | A type specification. data TypeSpec expectation  where   -- | Expect the given expectations to hold. If the compiler does not reject it -@@ -29,8 +33,6 @@   Invalid :: (DontTry (EvalExpectation expectation))         => TypeSpec expectation --- * Expectations- -- | An open family of type level expectation evaluators, that return  either @()@ -- or an @ErrorMessage@. type family EvalExpectation (expectation :: k) :: Result k@@ -48,14 +50,11 @@ type instance EvalExpectation (expectation ': rest) =   Cons'' <$> EvalExpectation expectation <*> EvalExpectation rest --- * Pretty Printing  -- | A class for pretty printing via the 'Show' instance of 'TypeSpec'. class PrettyTypeSpec (t :: k) where   prettyTypeSpec :: proxy t -> Doc --- * Printing/Showing- instance PrettyTypeSpec t => Show (TypeSpec t) where   show px@Valid =     render@@ -86,7 +85,7 @@   => PrettyTypeSpec '(expectation1, expectation2)   where     prettyTypeSpec _ =-        prettyTypeSpec pe1 $+$ prettyTypeSpec pe2 +        prettyTypeSpec pe1 $+$ prettyTypeSpec pe2       where pe1 = Proxy :: Proxy expectation1             pe2 = Proxy :: Proxy expectation2 
src/Test/TypeSpec/Group.hs view
@@ -1,6 +1,6 @@--- | Group expectations+-- | Composed Expectations. module Test.TypeSpec.Group-    ( type (-/-), type (-*) )+    ( type (-/-) )   where  import Data.Proxy@@ -9,34 +9,30 @@ import Test.TypeSpec.Internal.Either () import Text.PrettyPrint --- * Composed Expectations+{-| Combine two expectations. --- | A @cons@ like operator.--- Make a list of expectations. Use this to chain together any expectations--- especially those using '(~~~)' or '(-*)', since it has a lower precedence--- than both.+Make a collection of expectations:++>   (2 + 2)  `Is`     4+>                           -/-+>   (4 + 4)  `Is`     8+>                           -/-+>   'True    `IsNot` 'False+-} data expectation1 -/- expectation2 infixr 1 -/-  type instance   EvalExpectation (expectation -/- expectations) =-    TyCon2 ((-/-)) <$> EvalExpectation expectation <*> EvalExpectation expectations---- | A @cons@ like operator.--- Make a list of expectations. Use this to chain together anything /below/ or--- inside '(-/-)' and '(~~~)' parts. The precedence of this operator is higher--- that that of '(-/-)'.-type expectation1 -* expectation2 = expectation1 -/- expectation2-infixr 3 -*---- * Pretty Printing Instances+    TyCon2 (-/-) <$> EvalExpectation expectation <*> EvalExpectation expectations +-- | Pretty Printing Instance. instance     ( PrettyTypeSpec expectation1     , PrettyTypeSpec expectation2 )   => PrettyTypeSpec (expectation1 -/- expectation2)   where     prettyTypeSpec _ =-        (prettyTypeSpec pe1) $+$ (prettyTypeSpec pe2)+        prettyTypeSpec pe1 $+$ prettyTypeSpec pe2       where pe1 = Proxy :: Proxy expectation1             pe2 = Proxy :: Proxy expectation2
src/Test/TypeSpec/Internal/Apply.hs view
@@ -1,42 +1,14 @@ -- | Useful abstractions for type level programming using. This reimplements -- parts of the singletons library, which is just too heavy of a dependency to -- carry around, when only three small types are used of it.-module Test.TypeSpec.Internal.Apply-    ( type (>>=)-    , type (>>)-    , type (<*>)-    , type (<$>$$)-    , type (<$>$)-    , type (<$>)-    , type TyCon1-    , type TyCon2-    , type Apply-    , TyFun, type TyFunData-    , type (~>)-    , type Cons''-    , type Cons'-    , type Pair''-    , type Pair'-    , type Const-    , type Const'-    , type Const''-    , Flip'-    , Flip-    , Flip_-    , type Flip__-    , Compose''-    , Compose'-    , Compose-    , type Compose_-    )-    where+module Test.TypeSpec.Internal.Apply where  import Data.Kind  -- | Bind to actions. type family  (>>=) (ma :: monad a)-       (f :: TyFunData (a :: Type) ((monad b) :: Type))+       (f :: a ~> ((monad b) :: Type))        :: monad b  -- | Execute one action and then the next, ignore the result of the first.@@ -48,25 +20,25 @@   (f :: m (a ~> b)) <*> (ma :: m a) :: m b where   mf <*> mx = mf >>= Apply (Flip (<$>$$)) mx --- | Tuple construction+-- * Tuple construction data Pair'' :: a ~> b ~> (a, b) data Pair'  :: a -> b ~> (a, b) type instance Apply Pair'' x = Pair' x type instance Apply (Pair' x) y = '(x, y) --- | List construction+-- * List construction data Cons'' :: a ~> [a] ~> [a] data Cons' :: a -> [a] ~> [a] type instance Apply Cons'' x = Cons' x type instance Apply (Cons' x) xs = x ': xs --- | Convert data types to Partially applicable type functions+-- * Convert data types to Partially applicable type functions data TyCon1 :: (a -> b) -> a ~> b data TyCon2 :: (a -> b -> c) -> a ~> b ~> c type instance Apply (TyCon1 f) x = f x type instance Apply (TyCon2 f) x = (TyCon1 (f x)) --- | Execute an action and map a pure function over the result.+-- * Execute an action and map a pure function over the result. data (<$>$$) :: (a ~> b) ~> m a ~> m b data (<$>$) :: (a ~> b) -> m a ~> m b type instance Apply (<$>$$) f = (<$>$) f@@ -75,7 +47,6 @@   (f :: (a ~> b)) <$> (ma :: m a) :: m b  -- * Flip Type Functions- data Flip' :: (a ~> b ~> c) ~> b ~> a ~> c data Flip :: (a ~> b ~> c) -> b ~> a ~> c data Flip_ :: (a ~> b ~> c) -> b -> a ~> c@@ -87,7 +58,6 @@   Flip__ f y x = Apply (Apply f x) y  -- * Type Function composition- data Compose'' :: (b ~> c) ~> (a ~> b) ~> (a ~> c) data Compose' :: (b ~> c) -> (a ~> b) ~> (a ~> c) data Compose :: (b ~> c) -> (a ~> b) -> (a ~> c)@@ -100,17 +70,14 @@   -- * Type-Level 'const'- type family Const (a :: t) (b :: t') :: t where Const a b = a-data Const' :: a -> (TyFunData b a)-data Const'' :: TyFunData a (TyFunData b a)+data Const' :: a -> (b ~> a)+data Const'' :: a ~> (b ~> a) type instance Apply Const'' a = Const' a type instance Apply (Const' a) b = Const a b  -- * Defunctionalization- data TyFun :: Type -> Type -> Type-type TyFunData a b = TyFun a b -> Type type a ~> b = TyFun a b -> Type infixr 0 ~> type family Apply (f :: a ~> b) (x :: a) :: b
src/Test/TypeSpec/Internal/Either.hs view
@@ -1,16 +1,19 @@ -- | Useful abstractions for type level programming using 'Either'. module Test.TypeSpec.Internal.Either (type FromLeft) where -import Test.TypeSpec.Internal.Apply +import Test.TypeSpec.Internal.Apply --- * Either instances+-- * Either instances for '>>='  type instance (>>=) ('Right a) f = Apply f a type instance (>>=) ('Left b)  f = 'Left b +-- * Either instances for '<$>'+ type instance (<$>) f ('Right a) = 'Right (Apply f a) type instance (<$>) f ('Left a) = 'Left a +-- | Return the left type of a promoted 'Either' type family   FromLeft (e :: Either a b) :: a where   FromLeft ('Left a) = a
src/Test/TypeSpec/Internal/Equality.hs view
@@ -1,8 +1,13 @@ -- | Type Equality-module Test.TypeSpec.Internal.Equality (type PolyKindEq) where+module Test.TypeSpec.Internal.Equality (type EqExtra) where +  import Data.Type.Equality+   -- | Operator 'Data.Equality.(==)' expects both arguments to have the   -- same kind.-  type family PolyKindEq (a :: ak) (b :: bk) :: Bool where-    PolyKindEq a a = 'True-    PolyKindEq a b = 'False+  type family EqExtra (a :: ak) (b :: bk) :: Bool where+    EqExtra ('Left x) ('Left y) = EqExtra x y+    EqExtra ('Right x) ('Right y) = EqExtra x y+    EqExtra a a = 'True+    EqExtra (a :: k) (b :: k) = a == b+    EqExtra a b = 'False
src/Test/TypeSpec/Internal/Result.hs view
@@ -1,10 +1,15 @@--- | Result type used in constraints inside 'TypeSpec' to propagate type errors.+-- | A result type used in constraints inside 'TypeSpec' to chain computations+-- that may fail with a 'TypeError'. module Test.TypeSpec.Internal.Result-  ( type Result-  , type Try-  , type DontTry+  (+  -- * Results that with 'TypeErrors'+    type Result   , type FAILED   , type OK+  --  * Error propagation+  , type Try+  , type DontTry+  -- * Extending Error Messages   , type PrependToError   ) where @@ -13,18 +18,24 @@ import Test.TypeSpec.Internal.Apply () import Test.TypeSpec.Internal.Either () ---  * Type error propagation- -- | When a type level expectation is tested, it might be that compound -- expectations fail. In order to have a small, precise error message, the type -- level assertion results are made to have kind 'Result'. type Result = Either ErrorMessage +-- | A nice alias for 'Left'+type OK     = 'Right+-- | A nice alias for 'Right'+type FAILED = 'Left++-- | Return the result or fail with a 'TypeError' type family   Try (e :: Result k) :: k where   Try (OK     (d :: k)) = d   Try (FAILED m) = TypeError m +-- | A constraint that is satisfied if the parameter is 'Left'. Fails with a+-- 'TypeError' otherwise. type family   DontTry (e :: Result r) :: Constraint where   DontTry (FAILED e)     = ()@@ -35,10 +46,8 @@                ':$$:                'Text "... turns out it actually is!") --- | A nice name than 'Left'-type OK     = 'Right-type FAILED = 'Left-+-- | In case of @'Left' 'ErrorMessage'@ prepend a message to the message, if the+-- parameter was @'Right' x@ just return @'Right' x@. type family     PrependToError       (message :: ErrorMessage)
src/Test/TypeSpec/Label.hs view
@@ -1,4 +1,4 @@--- | Label expectations+-- | Labels for expectations. module Test.TypeSpec.Label     ( It )   where
src/Test/TypeSpec/ShouldBe.hs view
@@ -10,7 +10,7 @@  import Data.Kind import Data.Type.Bool-import Data.Type.Equality+ import Data.Typeable import GHC.TypeLits import Test.TypeSpec.Core@@ -24,7 +24,7 @@ data ShouldBeTrue :: expectation -> Type  type instance EvalExpectation (ShouldBeTrue t) =-    If (PolyKindEq t 'True)+    If (EqExtra t 'True)         (OK (ShouldBeTrue t))         (FAILED           ('Text "Should have been 'True: " ':<>: 'ShowType t))@@ -33,7 +33,7 @@ data ShouldBeFalse :: expectation -> Type  type instance EvalExpectation (ShouldBeFalse t) =-    If (PolyKindEq t 'False)+    If (EqExtra t 'False)         (OK (ShouldBeFalse t))         (FAILED           ('Text "Should have been 'False: " ':<>: 'ShowType t))@@ -44,8 +44,8 @@  type instance   EvalExpectation (ButNot (ShouldBe expected actual) other) =-    If (expected == actual)-      (If (expected == other)+    If (EqExtra expected actual)+      (If (EqExtra expected other)           (FAILED             ('Text "Expected type: "              ':$$: 'Text "   " ':<>: 'ShowType expected@@ -61,7 +61,7 @@  type instance   EvalExpectation (ShouldBe expected actual) =-    If (PolyKindEq expected actual)+    If (EqExtra expected actual)         (OK (ShouldBe expected actual))         (FAILED           ('Text "Expected type: " ':<>: 'ShowType expected@@ -72,7 +72,7 @@  type instance   EvalExpectation (ShouldNotBe expected actual) =-    If (PolyKindEq expected actual)+    If (EqExtra expected actual)         (FAILED           ('Text "Expected type: "            ':$$: 'Text "   " ':<>: 'ShowType expected@@ -80,8 +80,6 @@            ':$$: 'Text "   " ':<>: 'ShowType actual))         (OK (ShouldNotBe expected actual)) --- * PrettyTypeSpec instances- instance PrettyTypeSpec (ShouldBeTrue a) where   prettyTypeSpec _px =     prettyBulletPoint $ text "Type == True"@@ -120,4 +118,4 @@  -- | Pretty print a test prefix by a bullet-point. prettyBulletPoint :: Doc -> Doc-prettyBulletPoint doc = text "•" <+> doc +prettyBulletPoint doc = text "•" <+> doc
src/Test/TypeSpecCrazy.hs view
@@ -1,78 +1,83 @@--- | Funny operators that are mere type aliases for the constructs in--- 'TypeSpec'+-- | Funny operators that are mere type aliases for the constructs in 'TypeSpec' module Test.TypeSpecCrazy-      ( module Test.TypeSpecCrazy+      (+      -- * Crazy Type operators for 'It'+      type (--*)+      , type (~~~)+      , type (~~~~~~)+      , type (~~~~~~~~~)+      , type (~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      , type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)+      -- * Crazy Type operators for 'TypeSpec'+      , type (###)+      , type (######)+      , type (#########)+      , type (############)+      , type (###############)+      , type (##################)+      , type (#####################)+      , type (########################)+      , type (###########################)+      , type (##############################)+      , type (#################################)+      , type (####################################)+      , type (#######################################)+      , type (##########################################)+      , type (#############################################)+      , type (################################################)+      , type (###################################################)+      , type (######################################################)+      , type (#########################################################)+      , type (############################################################)+      , type (###############################################################)+      , type (##################################################################)+      , type (#####################################################################)+      , type (########################################################################)++        -- * Grouping Aliases+      , type (-*)+      , type (-*-)+       , module ReExport)     where  import Test.TypeSpec as ReExport --- * Crazy Type operators---- | Create a 'TypeSpec' with an initial description or title followed by some--- expectations. Note that the number of @#@s is alway a multiple of 3.-type (###) title expr = Explain title expr-type (######) title expr = Explain title expr-type (#########) title expr = Explain title expr-type (############) title expr = Explain title expr-type (###############) title expr = Explain title expr-type (##################) title expr = Explain title expr-type (#####################) title expr = Explain title expr-type (########################) title expr = Explain title expr-type (###########################) title expr = Explain title expr-type (##############################) title expr = Explain title expr-type (#################################) title expr = Explain title expr-type (####################################) title expr = Explain title expr-type (#######################################) title expr = Explain title expr-type (##########################################) title expr =-  Explain title expr-type (#############################################) title expr =-  Explain title expr-type (################################################) title expr =-  Explain title expr-type (###################################################) title expr =-  Explain title expr-type (######################################################) title expr =-  Explain title expr-type (#########################################################) title expr =-  Explain title expr-type (############################################################) title expr =-  Explain title expr-type (###############################################################) title expr =-  Explain title expr-type (##################################################################) title expr =-  Explain title expr-type (#####################################################################) title expr =-  Explain title expr-type (########################################################################) title expr =-  Explain title expr+{-| Alias for 'It', note that the number of @~@s is alway a multiple of 3. This+provides the impression of an underlined title followed by other expectations. -infixr 0 ###-infixr 0 ######-infixr 0 #########-infixr 0 ############-infixr 0 ###############-infixr 0 ##################-infixr 0 #####################-infixr 0 ########################-infixr 0 ###########################-infixr 0 ##############################-infixr 0 #################################-infixr 0 ####################################-infixr 0 #######################################-infixr 0 ##########################################-infixr 0 #############################################-infixr 0 ################################################-infixr 0 ###################################################-infixr 0 ######################################################-infixr 0 #########################################################-infixr 0 ############################################################-infixr 0 ###############################################################-infixr 0 ##################################################################-infixr 0 #####################################################################-infixr 0 ########################################################################+It allows to write the following type: --- | Specify an expectation using an underlined title using 'It'.+>+> type ExpectationWithTitle =+>   TypeSpec (+>+>      "This is a title for some assertions:"+>      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+>+>      (2 + 2)  `Is`   4+>+>    )+ -} type (--*) title expr = It title expr type (~~~) title expr = It title expr type (~~~~~~) title expr = It title expr@@ -110,31 +115,152 @@ type (~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~) title expr =   It title expr -infixl 2 --*-infixl 2 ~~~-infixr 2 ~~~~~~-infixr 2 ~~~~~~~~~-infixr 2 ~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-infixr 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 --*+infixr 3 ~~~+infixr 3 ~~~~~~+infixr 3 ~~~~~~~~~+infixr 3 ~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+infixr 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{-| Create a 'TypeSpec' with an initial description or title followed by some+expectations. Note that the number of @#@s is alway a multiple of 3.++It allows to rewrite the example above in a shorter way:++>+> type ExpectationWithTitleShorter =+>+>   "This is a title for some assertions:"+>   ######################################+>+>   (2 + 2)  `Is`   4+>++-}+type (###) title expr = Explain title expr+type (######) title expr = Explain title expr+type (#########) title expr = Explain title expr+type (############) title expr = Explain title expr+type (###############) title expr = Explain title expr+type (##################) title expr = Explain title expr+type (#####################) title expr = Explain title expr+type (########################) title expr = Explain title expr+type (###########################) title expr = Explain title expr+type (##############################) title expr = Explain title expr+type (#################################) title expr = Explain title expr+type (####################################) title expr = Explain title expr+type (#######################################) title expr = Explain title expr+type (##########################################) title expr =+  Explain title expr+type (#############################################) title expr =+  Explain title expr+type (################################################) title expr =+  Explain title expr+type (###################################################) title expr =+  Explain title expr+type (######################################################) title expr =+  Explain title expr+type (#########################################################) title expr =+  Explain title expr+type (############################################################) title expr =+  Explain title expr+type (###############################################################) title expr =+  Explain title expr+type (##################################################################) title expr =+  Explain title expr+type (#####################################################################) title expr =+  Explain title expr+type (########################################################################) title expr =+  Explain title expr++infixr 1 ###+infixr 1 ######+infixr 1 #########+infixr 1 ############+infixr 1 ###############+infixr 1 ##################+infixr 1 #####################+infixr 1 ########################+infixr 1 ###########################+infixr 1 ##############################+infixr 1 #################################+infixr 1 ####################################+infixr 1 #######################################+infixr 1 ##########################################+infixr 1 #############################################+infixr 1 ################################################+infixr 1 ###################################################+infixr 1 ######################################################+infixr 1 #########################################################+infixr 1 ############################################################+infixr 1 ###############################################################+infixr 1 ##################################################################+infixr 1 #####################################################################+infixr 1 ########################################################################++{-| Crazy operator alias for '-/-' with higher precedence.++It allows to group expectations more beautiful than using type level lists.++> specCrazyMoreNested ::+>+>   "Title"+>   ######+>+>     "Top-level "+>     ~~~~~~~~~~~~+>+>          "Nested:"+>          ~~~~~~~~~+>          Int `Is` Int+>                             -*-+>          Int `Is` Int+>                             -*-+>          Int `Is` Int+>+>                             -/-+>+>     "Top-level "+>     ~~~~~~~~~~~~+>+>          "Nested:"+>          ~~~~~~~~~+>          Int `Is` Int+>                             -*-+>              "Nested:"+>              ~~~~~~~~~+>              Int `Is` Int+>                             -*-+>              Int `Is` Int+>+> specCrazyMoreNested = Valid++-} type expectation1 -*- expectation2 = expectation1 -/- expectation2-infixl 2 -*-+infixr 3 -*-++-- | Crazy operator alias for '-/-'.+--+-- Make a list of expectations.  The precedence of this operator is even higher+-- than that of '-*-'.+type expectation1 -* expectation2 = expectation1 -/- expectation2+infixr 4 -*
+ stack.yaml view
@@ -0,0 +1,67 @@+# This file was automatically generated by 'stack init'+#+# Some commonly used options have been documented as comments in this file.+# For advanced use and comprehensive documentation of the format, please see:+# http://docs.haskellstack.org/en/stable/yaml_configuration/++# Resolver to choose a 'specific' stackage snapshot or a compiler version.+# A snapshot resolver dictates the compiler version and the set of packages+# to be used for project dependencies. For example:+#+# resolver: lts-3.5+# resolver: nightly-2015-09-21+# resolver: ghc-7.10.2+# resolver: ghcjs-0.1.0_ghc-7.10.2+# resolver:+#  name: custom-snapshot+#  location: "./custom-snapshot.yaml"+resolver: nightly-2016-07-30++# User packages to be built.+# Various formats can be used as shown in the example below.+#+# packages:+# - some-directory+# - https://example.com/foo/bar/baz-0.0.2.tar.gz+# - location:+#    git: https://github.com/commercialhaskell/stack.git+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a+#   extra-dep: true+#  subdirs:+#  - auto-update+#  - wai+#+# A package marked 'extra-dep: true' will only be built if demanded by a+# non-dependency (i.e. a user package), and its expr suites and benchmarks+# will not be run. This is useful for tweaking upstream packages.+packages:+- '.'+# Dependency packages to be pulled from upstream that are not in the resolver+# (e.g., acme-missiles-0.3)+extra-deps:+  - show-type-0.1.1++# Override default flag values for local packages and extra-deps+flags: {}++# Extra package databases containing global packages+extra-package-dbs: []++# Control whether we use the GHC we find on the path+# system-ghc: true+#+# Require a specific version of stack, using version ranges+# require-stack-version: -any # Default+# require-stack-version: ">=1.1"+#+# Override the architecture used by stack, especially useful on Windows+# arch: i386+# arch: x86_64+#+# Extra directories used by stack for building+# extra-include-dirs: [/path/to/dir]+# extra-lib-dirs: [/path/to/dir]+#+# Allow a newer minor version of GHC than the snapshot specifies+# compiler-check: newer-minor
type-spec.cabal view
@@ -1,5 +1,5 @@ name:                 type-spec-version:              0.1.0.0+version:              0.2.0.0 synopsis:             Type Level Specification by Example description:          Please see README.md homepage:             https://github.com/sheyll/type-spec#readme@@ -8,10 +8,13 @@ author:               Sven Heyll maintainer:           sven.heyll@gmail.com copyright:            2016 Sven Heyll-category:             expring+category:             Testing build-type:           Simple--- extra-source-files:-cabal-version:       >=1.10+extra-source-files:   examples/Main.hs+                    , README.md+                    , stack.yaml+                    , .travis.yml+cabal-version:        >=1.10  library   hs-source-dirs:      src