packages feed

typelits-witnesses (empty) → 0.1.0.0

raw patch · 5 files changed

+607/−0 lines, 5 filesdep +basedep +constraintsdep +reflectionsetup-changed

Dependencies added: base, constraints, reflection

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Justin Le++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
+ src/GHC/TypeLits/List.hs view
@@ -0,0 +1,312 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Module      : GHC.TypeLits.List+-- Description : Typeclasses, singletons, and reifiers for type-level lists+--               of 'Nat's and 'Symbol's.+-- Copyright   : (c) Justin Le 2015+-- License     : MIT+-- Maintainer  : justin@jle.im+-- Stability   : unstable+-- Portability : non-portable+--+--+-- Provides the 'KnownNats' and 'KnownSymbols' typeclasses in analogy to+-- 'KnownNat' and 'KnownSymbol' from "GHC.TypeLits".  Also provides+-- singleton-esque structures for traversing over type-level lists of+-- 'Nat's and 'Symbol's.  Comes with continuation-style reifiers and+-- existential types for dependent typing usage, and as an analogy with+-- 'SomeNat' and 'SomeSymbol'.+--+-- See typeclass documentations for more information.++module GHC.TypeLits.List (+  -- * @KnownNats@+    KnownNats(..)+  , SomeNats(..)+  , NatList(..)+  , someNatsVal+  , someNatsVal'+  , reifyNats+  , traverseNatList+  , traverseNatList'+  , traverseNatList_+  , mapNatList+  -- * @KnownSymbols@+  , KnownSymbols(..)+  , SomeSymbols(..)+  , SymbolList(..)+  , someSymbolsVal+  , reifySymbols+  , traverseSymbolList+  , traverseSymbolList'+  , traverseSymbolList_+  , mapSymbolList+  ) where++import Data.Proxy+import Data.Reflection+import GHC.TypeLits+import Data.Functor.Identity++-- | @'KnownNats' ns@ is intended to represent that every 'Nat' in the+-- type-level list 'ns' is itself a 'KnownNat' (meaning, you can use+-- 'natVal' to get its corresponding 'Integer').+--+-- In practice, just knowing that every item has a 'KnownNat' instance is+-- not enough; it's nice, but unless you're able to "iterate" over every+-- 'Nat' in the list, it's of limited use.  That's why this class also+-- provides a constructor for @'NatList' ns@, so that you can produce+-- a 'NatList' for every @'KnownNat' ns@, which you can iterate over to get+-- @'Proxy' n@s for every 'n' in 'ns' along with the @'KnownNat' n@+-- instances.+--+-- It also has an analogy to 'natVal', 'natsVal', which lets you get a list+-- of the represented 'Integer's for, say, @'Proxy' [1,2,3]@.+class KnownNats (ns :: [Nat]) where+    natsVal  :: p ns -> [Integer]+    natsList :: NatList ns++instance KnownNats '[] where+    natsVal  _ = []+    natsList   = ØNL++instance (KnownNat n, KnownNats ns) => KnownNats (n ': ns) where+    natsVal  _ = natVal (Proxy :: Proxy n) : natsVal (Proxy :: Proxy ns)+    natsList   = Proxy :<# natsList++-- | Represents unknown type-level lists of type-level natural numbers.+-- It's a 'NatList', but you don't know what the list contains at+-- compile-time.+data SomeNats :: * where+    SomeNats :: KnownNats ns => NatList ns -> SomeNats++-- | Singleton-esque type for "traversing" over type-level lists of 'Nat's.+-- Essentially contains a (value-level) list of @'Proxy' n@s, but each 'n'+-- has a 'KnownNat' instance for you to use.  At runtime (after type+-- erasure), is more or less equivalent to a @['Integer']@.+--+-- Typically generated using 'natsList'.+data NatList :: [Nat] -> * where+    ØNL   :: NatList '[]+    (:<#) :: (KnownNat n, KnownNats ns) => Proxy n -> NatList ns -> NatList (n ': ns)++infixr 5 :<#+deriving instance Show (NatList ns)++-- | Utility function for traversing over all of the @'Proxy' n@s in+-- a 'NatList', each with the corresponding 'KnownNat' instance available.+-- Gives the the ability to "change" the represented natural number to+-- a new one, in a 'SomeNat'.+--+-- Can be considered a form of a @Traversal' 'SomeNat' 'SomeNats'@.+traverseNatList :: forall f ns. Applicative f+                => (forall n. KnownNat n => Proxy n -> f SomeNat)+                -> NatList ns+                -> f SomeNats+traverseNatList f = go+  where+    go :: forall ms. NatList ms -> f SomeNats+    go nl = case nl of+              ØNL       -> pure $ SomeNats ØNL+              p :<# nl' -> merge <$> f p <*> go nl'+    merge :: SomeNat -> SomeNats -> SomeNats+    merge sn sns = case sn of+                     SomeNat i ->+                       case sns of+                         SomeNats is ->+                           SomeNats (i :<# is)++-- | Like 'traverseNatList', but literally actually a+-- @Traversal' 'SomeNat' 'SomeNats'@, so is usable with lens-library+-- machinery.+traverseNatList' :: forall f. Applicative f+                 => (SomeNat -> f SomeNat)+                 -> SomeNats+                 -> f SomeNats+traverseNatList' f ns =+    case ns of+      SomeNats ns' -> traverseNatList (f . SomeNat) ns'++-- | Utility function for traversing over all of the @'Proxy' n@s in+-- a 'NatList', each with the corresponding 'KnownNat' instance available.+-- Results are ignored.+traverseNatList_ :: forall f a ns. Applicative f+                 => (forall n. KnownNat n => Proxy n -> f a)+                 -> NatList ns+                 -> f ()+traverseNatList_ f = go+  where+    go :: forall ms. NatList ms -> f ()+    go nl = case nl of+              ØNL       -> pure ()+              p :<# nl' -> f p *> go nl'++-- | Utility function for \"mapping\" over each of the 'Nat's in the+-- 'NatList'.+mapNatList :: (forall n. KnownNat n => Proxy n -> SomeNat)+           -> NatList ns+           -> SomeNats+mapNatList f = runIdentity . traverseNatList (Identity . f)++-- | List equivalent of 'someNatVal'.  Convert a list of integers into an+-- unknown type-level list of naturals.  Will return 'Nothing' if any of+-- the given 'Integer's is negative.+someNatsVal :: [Integer] -> Maybe SomeNats+someNatsVal []     = Just (SomeNats ØNL)+someNatsVal (n:ns) = do+    SomeNat  m  <- someNatVal n+    SomeNats ms <- someNatsVal ns+    return $ SomeNats (m :<# ms)++-- | List equivalent of 'reifyNat'.  Given a list of integers, takes+-- a function in an "environment" with a @'NatList' ns@ corresponding to+-- the given list, where every @n@ in @ns@ has a 'KnownNat' instance.+--+-- Essentially a continuation-style version of 'SomeNats'.+--+-- For compatability with 'reifyNat', be aware that this also produces+-- @'KnownNat' n@s where @n@ is negative, without complaining.+reifyNats :: [Integer] -> (forall ns. KnownNats ns => NatList ns -> r) -> r+reifyNats []     f = f ØNL+reifyNats (n:ns) f = reifyNat n $ \m ->+                       reifyNats ns $ \ms ->+                         f (m :<# ms)++-- | Like 'someNatsVal', but will also go ahead and produce 'KnownNat's+-- whose integer values are negative.  It won't ever error on producing+-- them, but extra care must be taken when using the produced 'SomeNat's.+someNatsVal' :: [Integer] -> SomeNats+someNatsVal' ns = reifyNats ns SomeNats++-- | @'KnownSymbols' ns@ is intended to represent that every 'Symbol' in the+-- type-level list 'ns' is itself a 'KnownSymbol' (meaning, you can use+-- 'symbolVal' to get its corresponding 'String').+--+-- You can use 'symbolsVal' to get the corresponding @['String']@ from+-- @'KnownSymbols' ns@.+--+-- For reasons discussed further in the documentation for 'KnownNats', this+-- also lets you generate a @'SymbolList' ns@, in order to iterate over the+-- type-level list of 'Symbol's and take advantage of their 'KnownSymbol'+-- instances.+class KnownSymbols (ns :: [Symbol]) where+    symbolsVal  :: p ns -> [String]+    symbolsList :: SymbolList ns++instance KnownSymbols '[] where+    symbolsVal  _ = []+    symbolsList    = ØSL++instance (KnownSymbol n, KnownSymbols ns) => KnownSymbols (n ': ns) where+    symbolsVal  _ = symbolVal (Proxy :: Proxy n) : symbolsVal (Proxy :: Proxy ns)+    symbolsList   = Proxy :<$ symbolsList++-- | Represents unknown type-level lists of 'Symbol's. It's a 'SymbolList',+-- but you don't know what the list contains at compile-time.+data SomeSymbols :: * where+    SomeSymbols :: KnownSymbols ns => SymbolList ns -> SomeSymbols++-- | Singleton-esque type for "traversing" over type-level lists of+-- 'Symbol's. Essentially contains a (value-level) list of @'Proxy' n@s,+-- but each 'n' has a 'KnownSymbol' instance for you to use.  At runtime+-- (after type erasure), is more or less equivalent to a @['String']@.+--+-- Typically generated using 'symbolsList'.+data SymbolList :: [Symbol] -> * where+    ØSL   :: SymbolList '[]+    (:<$) :: (KnownSymbol n, KnownSymbols ns) => Proxy n -> SymbolList ns -> SymbolList (n ': ns)++infixr 5 :<$+deriving instance Show (SymbolList ns)++-- | Utility function for traversing over all of the @'Proxy' n@s in+-- a 'SymbolList', each with the corresponding 'KnownSymbol' instance+-- available.  Gives the the ability to "change" the represented natural+-- number to a new one, in a 'SomeSymbol'.+--+-- Can be considered a form of a @Traversal' 'SomeSymbol' 'SomeSymbols'@.+traverseSymbolList :: forall f ns. Applicative f+                   => (forall n. KnownSymbol n => Proxy n -> f SomeSymbol)+                   -> SymbolList ns+                   -> f SomeSymbols+traverseSymbolList f = go+  where+    go :: forall ms. SymbolList ms -> f SomeSymbols+    go nl = case nl of+              ØSL       -> pure $ SomeSymbols ØSL+              p :<$ nl' -> merge <$> f p <*> go nl'+    merge :: SomeSymbol -> SomeSymbols -> SomeSymbols+    merge s sl = case s of+                   SomeSymbol ps ->+                     case sl of+                       SomeSymbols sl' ->+                         SomeSymbols (ps :<$ sl')++-- | Like 'traverseSymbolList', but literally actually a+-- @Traversal' 'SomeSymbol' 'SomeSymbols'@, so is usable with lens-library+-- machinery.+traverseSymbolList' :: forall f. Applicative f+                 => (SomeSymbol -> f SomeSymbol)+                 -> SomeSymbols+                 -> f SomeSymbols+traverseSymbolList' f ns =+    case ns of+      SomeSymbols ns' -> traverseSymbolList (f . SomeSymbol) ns'++-- | Utility function for traversing over all of the @'Proxy' n@s in+-- a 'SymbolList', each with the corresponding 'KnownSymbol' instance+-- available. Results are ignored.+traverseSymbolList_ :: forall f ns. Applicative f+                    => (forall n a. KnownSymbol n => Proxy n -> f a)+                    -> SymbolList ns+                    -> f ()+traverseSymbolList_ f = go+  where+    go :: forall ms. SymbolList ms -> f ()+    go nl = case nl of+              ØSL       -> pure ()+              p :<$ nl' -> f p *> go nl'++-- | Utility function for \"mapping\" over each of the 'Symbol's in the+-- 'SymbolList'.+mapSymbolList :: (forall n. KnownSymbol n => Proxy n -> SomeSymbol)+              -> SymbolList ns+              -> SomeSymbols+mapSymbolList f = runIdentity . traverseSymbolList (Identity . f)++-- | List equivalent of 'someNatVal'.  Convert a list of integers into an+-- unknown type-level list of naturals.  Will return 'Nothing' if any of+-- the given 'Integer's is negative.+someSymbolsVal :: [String] -> SomeSymbols+someSymbolsVal []     = SomeSymbols ØSL+someSymbolsVal (n:ns) =+    case someSymbolVal n of+      SomeSymbol m ->+        case someSymbolsVal ns of+          SomeSymbols ms ->+            SomeSymbols (m :<$ ms)++-- | List equivalent of 'reifyNat'.  Given a list of integers, takes+-- a function in an "environment" with a @'NatList' ns@ corresponding to+-- the given list, where every @n@ in @ns@ has a 'KnownNat' instance.+--+-- Essentially a continuation-style version of 'SomeSymbols'.+reifySymbols :: [String]+             -> (forall ns. KnownSymbols ns => SymbolList ns -> r)+             -> r+reifySymbols []     f = f ØSL+reifySymbols (n:ns) f = reifySymbol n $ \m ->+                          reifySymbols ns $ \ms ->+                            f (m :<$ ms)
+ src/GHC/TypeLits/Witnesses.hs view
@@ -0,0 +1,227 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE PolyKinds #-}++-- |+-- Module      : GHC.TypeLits.Witnesses+-- Description : Instance witnesses for various arithmetic operations on+--               GHC TypeLits.+-- Copyright   : (c) Justin Le 2015+-- License     : MIT+-- Maintainer  : justin@jle.im+-- Stability   : unstable+-- Portability : non-portable+--+--+-- This module provides witnesses for instances that result from the+-- various arithmetic operations on GHC TypeLits 'Nat' types.  In general,+-- if you have @'KnownNat' n@, GHC can't infer @'KnownNat' (n + 1)@; and if+-- you have @'KnownNat' m@, as well, GHC can't infer @'KnownNat' (n + m)@.+--+-- This can be extremely annoying when dealing with libraries and+-- applications where one regularly adds and subtracts type-level nats and+-- expects 'KnownNat' instances to follow.  For example, vector+-- concatenation of length-encoded vector types can be:+--+-- @+-- concat :: ('KnownNat' n, 'KnownNat' m) => Vector n a -> Vector m a -> Vector (n + m) a+-- @+--+-- But, now @n + m@ does not have a 'KnownNat' instance...which makes+-- operations like this extremely less useful!+--+-- At the highest level, this module can be used with 'withNatOp':+--+-- @+-- getDoubled :: forall n. 'KnownNat' n => 'Proxy' n -> 'Integer'+-- getDoubled p = 'withNatOp' ('%*') p ('Proxy' :: 'Proxy' 2) $+--     natVal ('Proxy' :: 'Proxy' (n * 2))+-- @+--+-- With the final argument of 'withNatOp', you can provide a result+-- computed in an environment where @n * 2@ is indeed an instance of+-- 'KnownNat'.+--+-- For more complex usage, you can directly manipulate witnesses and then+-- use them via pattern matching:+--+-- @+-- let pn = 'natDict' ('Proxy' :: 'Proxy' n)+--     p1 = 'natDict' ('Proxy' :: 'Proxy' 1)+--     p2 = 'natDict' ('Proxy' :: 'Proxy' 2)+-- in  case pn '%*' p2 '%+' p1 of+--       'Dict' -> 'natVal' ('Proxy' :: 'Proxy' (n * 2 + 1))+-- @+--+-- In the branch of the case statement, @n * 2 + 1@ indeed has a 'KnownNat'+-- instance.+--+-- Note that the operators have appropriate fixities to mimic value-level+-- arithmetic operations.+--+-- __WARNING__: '%-' and 'entailSub' are is implemented in a way such+-- that /negative/ 'KnownNat's are produced without any errors.  The+-- production of witnesses and entailments will hold, but be aware that any+-- functions that rely on 'KnownNat' instances to be non-negative can+-- potentially break.+++module GHC.TypeLits.Witnesses (+  -- * High level wrapper+    withNatOp+  -- * Direct witnesses+  , natDict+  , dictNatVal+  -- * Witness generators+  , (%+)+  , (%-)+  , (%*)+  , (%^)+  -- * Entailments+  , entailAdd+  , entailSub+  , entailMul+  , entailExp+  ) where++import Data.Constraint+import GHC.TypeLits+import Data.Proxy+import Data.Reflection+import Unsafe.Coerce++-- | Create a 'Dict' witness for @'KnownNat' n@.+natDict :: KnownNat n => Proxy n -> Dict (KnownNat n)+natDict _ = Dict++-- | Get the 'Integer' from the 'KnownNat' instance witnessed by the+-- 'Dict'.+dictNatVal :: forall n. Dict (KnownNat n) -> Integer+dictNatVal Dict = natVal (Proxy :: Proxy n)++infixl 6 %++infixl 6 %-+infixl 7 %*+infixr 8 %^++-- | Given witnesses for @'KnownNat' n@ and @'KnownNat' m@, generates+-- a witness for @'KnownNat' (n + m)@.+--+-- Follows proper association and fixity for usage with other similar+-- operators.+(%+) :: forall n m. Dict (KnownNat n) -> Dict (KnownNat m) -> Dict (KnownNat (n + m))+Dict %+ Dict = mapDict entailAdd (Dict :: Dict (KnownNat n, KnownNat m))++-- | Given witnesses for @'KnownNat' n@ and @'KnownNat' m@, generates+-- a witness for @'KnownNat' (n - m)@.+--+-- Note that this is implemented in a way such that /negative/ 'KnownNat's+-- are produced without any errors.+--+-- Follows proper association and fixity for usage with other similar+-- operators.+(%-) :: forall n m. Dict (KnownNat n) -> Dict (KnownNat m) -> Dict (KnownNat (n - m))+Dict %- Dict = mapDict entailSub (Dict :: Dict (KnownNat n, KnownNat m))++-- | Given witnesses for @'KnownNat' n@ and @'KnownNat' m@, generates+-- a witness for @'KnownNat' (n * m)@.+--+-- Follows proper association and fixity for usage with other similar+-- operators.+(%*) :: forall n m. Dict (KnownNat n) -> Dict (KnownNat m) -> Dict (KnownNat (n * m))+Dict %* Dict = mapDict entailMul (Dict :: Dict (KnownNat n, KnownNat m))++-- | Given witnesses for @'KnownNat' n@ and @'KnownNat' m@, generates+-- a witness for @'KnownNat' (n ^ m)@.+--+-- Follows proper association and fixity for usage with other similar+-- operators.+(%^) :: forall n m. Dict (KnownNat n) -> Dict (KnownNat m) -> Dict (KnownNat (n ^ m))+Dict %^ Dict = mapDict entailExp (Dict :: Dict (KnownNat n, KnownNat m))++-- | A high-level the interface of this module.  Give it one of+-- the witness-generating operators on 'KnownNat's in this module ('%+',+-- '%-', '%*', or '%^'), two 'Proxy's containing the 'KnownNat's to+-- be modified, and receive an environment where the result of the+-- operation (applied to the 'KnownNat's) has a 'KnownNat' instance.+--+-- For example, with+--+-- @+-- 'withNatOp' ('%+') ('Proxy' :: 'Proxy' n) ('Proxy' :: 'Proxy' 1) r+-- @+--+-- in @r@, @n + 1@ has a 'KnownNat' instance:+--+-- @+-- 'withNatOp' ('%+') ('Proxy' :: 'Proxy' n) ('Proxy' :: 'Proxy' 1) $+--     'natVal' ('Proxy' :: 'Proxy' (n + 1))+-- -- => will return the 'Integer' correpsonding to n + 1+-- @+--+-- Normally, if @n@ is a 'KnownNat' instance, it is not in general+-- inferrable that @n + 1@ also has a 'KnownNat' instance.  This combinator+-- makes it so.+--+-- For multiple operations on values, this can be chained:+--+-- @+-- 'withNatOp' ('%*') ('Proxy' :: 'Proxy' n) ('Proxy' :: 'Proxy' 2) $+--   'withNatOp' ('%+') ('Proxy' :: 'Proxy' (n*2)) ('Proxy' :: 'Proxy' 1) $+--     'natVal' ('Proxy' :: 'Proxy' (n * 2 + 1))+-- @+--+-- But, at this point, it's easier and simpler to just directly use the+-- operators and pattern match:+--+-- @+-- let pn = 'natDict' ('Proxy' :: 'Proxy' n)+--     p1 = 'natDict' ('Proxy' :: 'Proxy' 1)+--     p2 = 'natDict' ('Proxy' :: 'Proxy' 2)+-- in  case pn '%*' p2 '%+' p1 of+--       'Dict' -> 'natVal' ('Proxy' :: 'Proxy' (n * 2 + 1))+-- @+--+-- (Note that associativity and fixity for the witness-generating operators+-- are set to match that of normal addition and multiplication, etc.)+--+--+withNatOp :: (KnownNat n, KnownNat m)+          => (Dict (KnownNat n) -> Dict (KnownNat m) -> Dict (KnownNat q))+          -> Proxy n+          -> Proxy m+          -> (KnownNat q => r)+          -> r+withNatOp op x y r = case natDict x `op` natDict y of+                       Dict -> r++-- | An entailment for addition of 'KnownNat' instances.+entailAdd :: forall n m. (KnownNat n, KnownNat m) :- KnownNat (n + m)+entailAdd = Sub $+  reifyNat (natVal (Proxy :: Proxy n) + natVal (Proxy :: Proxy m)) $ \p ->+    unsafeCoerce (natDict p)++-- | An entailment for subtraction of 'KnownNat' instances.+--+-- Note that this is implemented in a way such that /negative/ 'KnownNat's+-- are produced without any errors.+entailSub :: forall n m. (KnownNat n, KnownNat m) :- KnownNat (n - m)+entailSub = Sub $+  reifyNat (natVal (Proxy :: Proxy n) - natVal (Proxy :: Proxy m)) $ \p ->+    unsafeCoerce (natDict p)++-- | An entailment for multiplication of 'KnownNat' instances.+entailMul :: forall n m. (KnownNat n, KnownNat m) :- KnownNat (n * m)+entailMul = Sub $+  reifyNat (natVal (Proxy :: Proxy n) * natVal (Proxy :: Proxy m)) $ \p ->+    unsafeCoerce (natDict p)++-- | An entailment for exponentiation of 'KnownNat' instances.+entailExp :: forall n m. (KnownNat n, KnownNat m) :- KnownNat (n ^ m)+entailExp = Sub $+  reifyNat (natVal (Proxy :: Proxy n) ^ natVal (Proxy :: Proxy m)) $ \p ->+    unsafeCoerce (natDict p)+
+ typelits-witnesses.cabal view
@@ -0,0 +1,46 @@+name:                typelits-witnesses+version:             0.1.0.0+synopsis:            Existential witnesses, singletons, and classes for operations on GHC TypeLits+description:         Provides witnesses for 'KnownNat' and 'KnownSymbol'+                     instances for various operations on GHC TypeLits - in+                     particular, the arithmetic operations defined in+                     "GHC.TypeLits", and also for type-level lists of+                     'KnownNat' and 'KnownSymbol' instances.+                     .+                     This is useful for situations where you have+                     @'KnownNat' n@, and you want to prove to GHC+                     @'KnownNat' (n + 3)@, or @'KnownNat' (2*n + 4)@.+                     .+                     It's also useful for when you want to work with type+                     level lists of 'KnownNat' or 'KnownSymbol' instances and+                     singletons for traversing them, and be able to apply+                     analogies of 'natVal' and 'symbolVal' to lists with+                     analogies for 'SomeNat' and 'SomeSymbol'.+                     .+                     See README for more information.+homepage:            https://github.com/mstksg/typelits-witnesses+license:             MIT+license-file:        LICENSE+author:              Justin Le+maintainer:          justin@jle.im+copyright:           (c) Justin Le 2015+category:            Data+build-type:          Simple+-- extra-source-files:  +cabal-version:       >=1.10++source-repository head+  type:              git+  location:          git://github.com/mstksg/typelits-witnesses.git++library+  exposed-modules:     GHC.TypeLits.Witnesses+                       GHC.TypeLits.List+  -- other-modules:       +  -- other-extensions:    +  build-depends:       base >=4.8 && <4.9+                     , reflection+                     , constraints+  hs-source-dirs:      src+  ghc-options:         -Wall+  default-language:    Haskell2010