packages feed

indextype (empty) → 0.1.0.0

raw patch · 7 files changed

+609/−0 lines, 7 filesdep +basedep +hspecsetup-changed

Dependencies added: base, hspec

Files

+ LICENSE view
@@ -0,0 +1,19 @@+Copyright 2017 Clinton Mead++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+of the Software, and to permit persons to whom the Software is furnished to do+so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ indextype.cabal view
@@ -0,0 +1,38 @@+name:                 indextype+version:              0.1.0.0+synopsis: A series of type families and constraints for "indexable" types.+description:+  This package deals with types that can roughly be "indexed" at compile time by an integer.+  For example, tuples and be indexed by their nth elements, and functions by their nth argument.+  A number of type functions allow one to extract these subtypes, i.e. the type of the 2nd element of a given tuple.++  Furthermore, constraints are defined which allow one to easily constrain types to these index types,+  e.g. a constraint that says "@t@ is a 3 tuple". @Control.IndexT@ has more detail.+author:               Clinton Mead+maintainer:           clintonmead@gmail.com+category:             Control+license: MIT+license-file: LICENSE+copyright: Clinton Mead (2017)+build-type:           Simple+cabal-version:        >=1.10+tested-with: GHC == 8.0.2+bug-reports:++source-repository head+  type: git+  location: https://github.com/clintonmead/indextype.git++library+  exposed-modules:      Control.IndexT, Control.IndexT.Tuple, Control.IndexT.Function+  build-depends:        base >= 4.7 && < 5+  hs-source-dirs:       src+  default-language:     Haskell2010++Test-Suite tests+  type: exitcode-stdio-1.0+  main-is: Tests.hs+  other-modules: Control.IndexT, Control.IndexT.Tuple, Control.IndexT.Function+  build-depends:        base >= 4.7 && < 5, hspec+  hs-source-dirs:       test, src+  default-language:     Haskell2010
+ src/Control/IndexT.hs view
@@ -0,0 +1,221 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}++{-|+Module      : Control.IndexT+Copyright   : Clinton Mead, 2017+License     : MIT+Maintainer  : clintonmead@gmail.com+Stability   : experimental+Portability : GHC++This package is useful for dealing with for what I have called "indexed types". This is perhaps not a great choice of+name (alternative suggestions welcome) but basically I'm talking about types where you can "index" them like an array.+A tuple is a good example.++This particular module gives you a type function 'IndexT' that allows you to get the type of the say, third+element of a tuple.++But the other modules in this package, "Control.IndexT.Tuple" and "Control.IndexT.Function", build on this.++For example, occasionally you'll want to write a constraint like this:++> t ~ (t1,t2)++i.e. @t@ is a pair. But if @t1@ and @t2@ are not in scope, GHC will complain.++This package contains some type family and class defined constraints that allow you to+make constraints like "@t@ is a pair".++The type families are open, so you can extend this+module for your own data types.++More detailed usage information is in the documentation, both below. and also in "Control.IndexT.Tuple".++Currently this library deals with tuples up to length 15 and functions with up to 15 arguments.+Let me know if you need anything bigger.+-}++module Control.IndexT (+  IndexT+  ) where++import GHC.TypeLits (Nat)+import GHC.Exts (Constraint)+import Data.Functor.Identity (Identity)++{-|+'IndexT' is the core type family of this module. @IndexT n a@ gets the type of the "nth" element of @a@.+In this module, 'IndexT' is defined on tuples and functions, and is zero based.++So++> IndexT 0 (a, b, c) == a++and++> IndexT 0 (a -> b -> c) == a++Note the following:++> IndexT 1 (a -> b -> c) == b+> IndexT 2 (a, b, c) == c++but...++> IndexT 2 (a -> b -> c) /= c -- (it's actually not defined)++This is because the way functions are defined. Consider a function of three arguments:++> f :: a -> b -> c -> d++For this function, we want:++> IndexT 2 (a -> b -> c -> d) == c++But if we defined 'IndexT' like the following:++> IndexT 2 (a -> b -> c) = c++Then we would find that:++> IndexT 2 (a -> b -> c -> d) == IndexT 2 (a -> b -> (c -> d)) == (c -> d)++Which is not right. For this reason, 'IndexT' can not get the "result" type of functions, you'll need to use 'ResultT' for that.+-}+type family IndexT (i :: Nat) a+type instance IndexT 0 (Identity a) = a+type instance IndexT 0 (a, _) = a+type instance IndexT 1 (_, a) = a+type instance IndexT 0 (a, _, _) = a+type instance IndexT 1 (_, a, _) = a+type instance IndexT 2 (_, _, a) = a+type instance IndexT 0 (a, _, _, _) = a+type instance IndexT 1 (_, a, _, _) = a+type instance IndexT 2 (_, _, a, _) = a+type instance IndexT 3 (_, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _) = a+type instance IndexT 3 (_, _, _, a, _) = a+type instance IndexT 4 (_, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _) = a+type instance IndexT 5 (_, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 10 (_, _, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 10 (_, _, _, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 11 (_, _, _, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 10 (_, _, _, _, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 11 (_, _, _, _, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 12 (_, _, _, _, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 10 (_, _, _, _, _, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 11 (_, _, _, _, _, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 12 (_, _, _, _, _, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 13 (_, _, _, _, _, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 1 (_, a, _, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 2 (_, _, a, _, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 3 (_, _, _, a, _, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 4 (_, _, _, _, a, _, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 5 (_, _, _, _, _, a, _, _, _, _, _, _, _, _, _) = a+type instance IndexT 6 (_, _, _, _, _, _, a, _, _, _, _, _, _, _, _) = a+type instance IndexT 7 (_, _, _, _, _, _, _, a, _, _, _, _, _, _, _) = a+type instance IndexT 8 (_, _, _, _, _, _, _, _, a, _, _, _, _, _, _) = a+type instance IndexT 9 (_, _, _, _, _, _, _, _, _, a, _, _, _, _, _) = a+type instance IndexT 10 (_, _, _, _, _, _, _, _, _, _, a, _, _, _, _) = a+type instance IndexT 11 (_, _, _, _, _, _, _, _, _, _, _, a, _, _, _) = a+type instance IndexT 12 (_, _, _, _, _, _, _, _, _, _, _, _, a, _, _) = a+type instance IndexT 13 (_, _, _, _, _, _, _, _, _, _, _, _, _, a, _) = a+type instance IndexT 14 (_, _, _, _, _, _, _, _, _, _, _, _, _, _, a) = a+type instance IndexT 0 (a -> _) = a+type instance IndexT 1 (_ -> a -> _) = a+type instance IndexT 2 (_ -> _ -> a -> _) = a+type instance IndexT 3 (_ -> _ -> _ -> a -> _) = a+type instance IndexT 4 (_ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 5 (_ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 6 (_ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 7 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 8 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 9 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 10 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 11 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 12 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a+type instance IndexT 13 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a -> _) = a
+ src/Control/IndexT/Function.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE FlexibleInstances #-}++{-|+Type family and class definitions for dealing with functions.++Many of these definitions are similar to the ones that deal with tuples, in which case+it refers to the documentation in "Control.IndexT.Tuple".++Also see the "Control.IndexT" module description for an overview.+-}+++module Control.IndexT.Function (+  ResultT,+  FuncN,+  FuncConstraint,+  HomoFuncConstraint,+  HomoArgFuncConstraint,+  IsFunc,+  IsHomoFunc,+  IsHomoArgFunc+  )+where++import Control.IndexT (IndexT)++import GHC.TypeLits (Nat)+import GHC.Exts (Constraint)+++{-|+'ResultT' is used to get the result type of functions, which 'IndexT' can not be used for as discussed in+it's documentation.++@ResultT n t@ gets the result of @t@ treated as an @n@ argument function. For example:++> ResultT 2 (a -> b -> c) == c++note that:++> ResultT 2 (a -> b -> c -> d) == c -> d++which makes sense, as the result of applying two arguments to this function is @(c -> d)@.+-}+type family ResultT (n :: Nat) a+type instance ResultT 0 (a) = a+type instance ResultT 1 (_ -> a) = a+type instance ResultT 2 (_ -> _ -> a) = a+type instance ResultT 3 (_ -> _ -> _ -> a) = a+type instance ResultT 4 (_ -> _ -> _ -> _ -> a) = a+type instance ResultT 5 (_ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 6 (_ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 7 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 8 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 9 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 10 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 11 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 12 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 13 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 14 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a+type instance ResultT 15 (_ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> _ -> a) = a++{-|+Like 'Control.IndexT.TupleN', but for functions.+-}+type family FuncN (n :: Nat) a+type instance FuncN 0 a = a+type instance FuncN 1 a = IndexT 0 a -> ResultT 1 a+type instance FuncN 2 a = IndexT 0 a -> IndexT 1 a -> ResultT 2 a+type instance FuncN 3 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> ResultT 3 a+type instance FuncN 4 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> ResultT 4 a+type instance FuncN 5 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> ResultT 5 a+type instance FuncN 6 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> ResultT 6 a+type instance FuncN 7 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> ResultT 7 a+type instance FuncN 8 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> ResultT 8 a+type instance FuncN 9 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> ResultT 9 a+type instance FuncN 10 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> ResultT 10 a+type instance FuncN 11 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> IndexT 10 a -> ResultT 11 a+type instance FuncN 12 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> IndexT 10 a -> IndexT 11 a -> ResultT 12 a+type instance FuncN 13 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> IndexT 10 a -> IndexT 11 a -> IndexT 12 a -> ResultT 13 a+type instance FuncN 14 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> IndexT 10 a -> IndexT 11 a -> IndexT 12 a -> IndexT 13 a -> ResultT 14 a+type instance FuncN 15 a = IndexT 0 a -> IndexT 1 a -> IndexT 2 a -> IndexT 3 a -> IndexT 4 a -> IndexT 5 a -> IndexT 6 a -> IndexT 7 a -> IndexT 8 a -> IndexT 9 a -> IndexT 10 a -> IndexT 11 a -> IndexT 12 a -> IndexT 13 a -> IndexT 14 a -> ResultT 15 a++{-|+Like 'Control.IndexT.TupleConstraint', but for functions.+-}+type FuncConstraint (n :: Nat) a = a ~ FuncN n a++{-|+Like 'Control.IndexT.HomoTupleConstraint', but for functions, where all arguments and the result type are the same.+-}+type HomoFuncConstraint (n :: Nat) a = (HomoArgFuncConstraint n a, ResultT n a ~ IndexT 0 a)++{-|+Like 'HomoFuncConstraint', but only constrains all the arguments to be the same type, not the result.+-}+type family HomoArgFuncConstraint (n :: Nat) a :: Constraint+type instance HomoArgFuncConstraint 0 a = (FuncConstraint 0 a)+type instance HomoArgFuncConstraint 1 a = (FuncConstraint 1 a)+type instance HomoArgFuncConstraint 2 a = (FuncConstraint 2 a, IndexT 0 a ~ IndexT 1 a)+type instance HomoArgFuncConstraint 3 a = (FuncConstraint 3 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a)+type instance HomoArgFuncConstraint 4 a = (FuncConstraint 4 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a)+type instance HomoArgFuncConstraint 5 a = (FuncConstraint 5 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a)+type instance HomoArgFuncConstraint 6 a = (FuncConstraint 6 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a)+type instance HomoArgFuncConstraint 7 a = (FuncConstraint 7 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a)+type instance HomoArgFuncConstraint 8 a = (FuncConstraint 8 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a)+type instance HomoArgFuncConstraint 9 a = (FuncConstraint 9 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a)+type instance HomoArgFuncConstraint 10 a = (FuncConstraint 10 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a)+type instance HomoArgFuncConstraint 11 a = (FuncConstraint 11 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a)+type instance HomoArgFuncConstraint 12 a = (FuncConstraint 12 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a)+type instance HomoArgFuncConstraint 13 a = (FuncConstraint 13 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a)+type instance HomoArgFuncConstraint 14 a = (FuncConstraint 14 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a, IndexT 12 a ~ IndexT 13 a)+type instance HomoArgFuncConstraint 15 a = (FuncConstraint 15 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a, IndexT 12 a ~ IndexT 13 a, IndexT 13 a ~ IndexT 14 a)++{-|+Like 'Control.IndexT.IsTuple', but for functions.+-}+class (FuncConstraint n a) => IsFunc n a+instance (FuncConstraint n a) => IsFunc n a++{-|+Like 'Control.IndexT.IsHomoTuple', but for functions.+-}+class (HomoFuncConstraint n a) => IsHomoFunc n a+instance (HomoFuncConstraint n a) => IsHomoFunc n a++{-|+A classed based constraint for 'HomoArgFuncConstraint'.+-}+class (HomoArgFuncConstraint n a) => IsHomoArgFunc n a+instance (HomoArgFuncConstraint n a) => IsHomoArgFunc n a
+ src/Control/IndexT/Tuple.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE FlexibleInstances #-}++{-|+Type family and class definitions for dealing with tuples.++See the "Control.IndexT" module description for an overview.+-}++module Control.IndexT.Tuple (+  TupleN,+  TupleConstraint,+  HomoTupleConstraint,+  IsTuple,+  IsHomoTuple+  )+where++import Control.IndexT (IndexT)++import GHC.TypeLits (Nat)+import GHC.Exts (Constraint)+import Data.Functor.Identity (Identity)++{-|+'TupleN' seems a bit weird, but it's an important part of defining constraints that allow one to say "@t@ is a pair"+in 'TupleConstraint'.+-}+type family TupleN (n :: Nat) a+type instance TupleN 0 a = ()+type instance TupleN 1 a = Identity a+type instance TupleN 2 a = (IndexT 0 a, IndexT 1 a)+type instance TupleN 3 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a)+type instance TupleN 4 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a)+type instance TupleN 5 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a)+type instance TupleN 6 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a)+type instance TupleN 7 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a)+type instance TupleN 8 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a)+type instance TupleN 9 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a)+type instance TupleN 10 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a)+type instance TupleN 11 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a, IndexT 10 a)+type instance TupleN 12 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a, IndexT 10 a, IndexT 11 a)+type instance TupleN 13 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a, IndexT 10 a, IndexT 11 a, IndexT 12 a)+type instance TupleN 14 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a, IndexT 10 a, IndexT 11 a, IndexT 12 a, IndexT 13 a)+type instance TupleN 15 a = (IndexT 0 a, IndexT 1 a, IndexT 2 a, IndexT 3 a, IndexT 4 a, IndexT 5 a, IndexT 6 a, IndexT 7 a, IndexT 8 a, IndexT 9 a, IndexT 10 a, IndexT 11 a, IndexT 12 a, IndexT 13 a, IndexT 14 a)++{-|+To best explain this, lets consider the particular example @TupleConstraint 2@.++As @TupleN 2 t = (IndexT 0 t, IndexT 1 t)@ we get:++> TupleConstraint 2 t = t ~ (IndexT 0 t, IndexT 1 t)++What does this say? Well, firstly, as @t ~ (IndexT 0 t, IndexT 1 t)@, it must be a pair at least.++What are the elements of the pair? Well, the first element of @t@ is @IndexT 0 t@.++And what's @IndexT 0 t@ defined as? The first element of @t@.++So we know that the first element of @t@ is well, the first element of @t@.++Which tells us nothing at all.++We can go through the same argument with the second element of @t@.++So all we know after this is that @t@ is a pair. @TupleConstraint 2 t@ is the same as saying @t@ is a pair.++So @TupleConstraint n t@ basically says @t@ is a n-tuple.+-}+type TupleConstraint (n :: Nat) a = a ~ TupleN n a++{-|+'HomoTupleConstraint' simply further constrains 'TupleConstraint' so that all the elements are the same.++So @HomoTupleConstraint 3 t@ basically says @t ~ (u,u,u)@ for some @u@,++("Homo" is short for "Homogeneous". Like milk.)+-}+type family HomoTupleConstraint (n :: Nat) a :: Constraint+type instance HomoTupleConstraint 0 a = (TupleConstraint 0 a)+type instance HomoTupleConstraint 1 a = (TupleConstraint 1 a)+type instance HomoTupleConstraint 2 a = (TupleConstraint 2 a, IndexT 0 a ~ IndexT 1 a)+type instance HomoTupleConstraint 3 a = (TupleConstraint 3 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a)+type instance HomoTupleConstraint 4 a = (TupleConstraint 4 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a)+type instance HomoTupleConstraint 5 a = (TupleConstraint 5 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a)+type instance HomoTupleConstraint 6 a = (TupleConstraint 6 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a)+type instance HomoTupleConstraint 7 a = (TupleConstraint 7 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a)+type instance HomoTupleConstraint 8 a = (TupleConstraint 8 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a)+type instance HomoTupleConstraint 9 a = (TupleConstraint 9 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a)+type instance HomoTupleConstraint 10 a = (TupleConstraint 10 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a)+type instance HomoTupleConstraint 11 a = (TupleConstraint 11 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a)+type instance HomoTupleConstraint 12 a = (TupleConstraint 12 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a)+type instance HomoTupleConstraint 13 a = (TupleConstraint 13 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a)+type instance HomoTupleConstraint 14 a = (TupleConstraint 14 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a, IndexT 12 a ~ IndexT 13 a)+type instance HomoTupleConstraint 15 a = (TupleConstraint 15 a, IndexT 0 a ~ IndexT 1 a, IndexT 1 a ~ IndexT 2 a, IndexT 2 a ~ IndexT 3 a, IndexT 3 a ~ IndexT 4 a, IndexT 4 a ~ IndexT 5 a, IndexT 5 a ~ IndexT 6 a, IndexT 6 a ~ IndexT 7 a, IndexT 7 a ~ IndexT 8 a, IndexT 8 a ~ IndexT 9 a, IndexT 9 a ~ IndexT 10 a, IndexT 10 a ~ IndexT 11 a, IndexT 11 a ~ IndexT 12 a, IndexT 12 a ~ IndexT 13 a, IndexT 13 a ~ IndexT 14 a)++{-|+GHC does not allow you to partially apply type families (or any type declaration for that matter).+So if you have a type of @* -> Constraint@ you can't pass @TupleConstraint 2@, because 'TupleConstraint' is partially+applied and this is not allowed.++But you can partially apply classes.++So 'IsTuple' is basically the same as 'TupleConstraint' except that it's a class, not a type family.+-}+class (TupleConstraint n a) => IsTuple n a+instance (TupleConstraint n a) => IsTuple n a++{-|+The version of 'IsTuple' for homogenous tuples (i.e. all the same type).+-}+class (HomoTupleConstraint n a) => IsHomoTuple n a+instance (HomoTupleConstraint n a) => IsHomoTuple n a+
+ test/Tests.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Main where++import Test.Hspec++import Control.IndexT+import Control.IndexT.Tuple+import Control.IndexT.Function++default ()++data TT where+  TT :: (forall t. (Integral (IndexT 0 t), Integral (IndexT 1 t), IsTuple 2 t) => t) -> TT++data HTT where+  HTT :: (forall t. (Num (IndexT 0 t), IsHomoTuple 2 t) => t) -> HTT++data FT where+  FT :: (forall t. (Num (IndexT 0 t), IndexT 1 t ~ Bool, IndexT 0 t ~ ResultT 2 t, IsFunc 2 t) => t) -> FT++data HFT where+  HFT :: (forall t. (Num (IndexT 0 t), IsHomoFunc 2 t) => t) -> HFT++data HAFT where+  HAFT :: (forall t. (Eq (IndexT 0 t), ResultT 2 t ~ Bool, IsHomoArgFunc 2 t) => t) -> HAFT++f1 :: TT -> Integer+f1 (TT (x :: (Int, Integer))) = toInteger (fst x) + toInteger (snd x)++f2 :: Num a => HTT -> a+f2 (HTT x) = fst x * snd x++f3 :: (Num a) => FT -> a -> Bool -> a+f3 (FT f) x y = f x y++f4 :: (Num a) => HFT -> a -> a -> a+f4 (HFT f) x y = f x y++f5 :: (Eq a) => HAFT -> a -> a -> Bool+f5 (HAFT f) x y = f x y++x1 :: Integer+x1 = f1 (TT (40,2))++x2 :: Int+x2 = f2 (HTT (12,7))++x3 :: Int+x3 = f3 (FT (\x y -> if y then x*2 else x*3)) 5 False++x4 :: Integer+x4 = f4 (HFT (+)) 40 3++x5 :: Bool+x5 = f5 (HAFT (==)) 'x' 'x'++main :: IO ()+main = hspec $ do+  it "Tuple Test" $ x1 `shouldBe` 42+  it "HomoTuple Test" $ x2 `shouldBe` 84+  it "Func Test" $ x3 `shouldBe` 15+  it "HomoFunc Test" $ x4 `shouldBe` 43+  it "HomoArgFunc Test" $ x5 `shouldBe` True