packages feed

type-unary 0.1.9 → 0.1.10

raw patch · 4 files changed

+260/−208 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- TypeUnary.Vec: Index :: (n :<: lim) -> (Nat n) -> Index lim
- TypeUnary.Vec: Succ :: Nat n -> Nat (S n)
- TypeUnary.Vec: Zero :: Nat Z
- TypeUnary.Vec: class IsNat n
- TypeUnary.Vec: data (:<:) m n
- TypeUnary.Vec: data Index lim
- TypeUnary.Vec: data Nat :: * -> *
- TypeUnary.Vec: data S n
- TypeUnary.Vec: data Z
- TypeUnary.Vec: four :: Nat N4
- TypeUnary.Vec: index0 :: Index (N1 :+: m)
- TypeUnary.Vec: index1 :: Index (N2 :+: m)
- TypeUnary.Vec: index2 :: Index (N3 :+: m)
- TypeUnary.Vec: index3 :: Index (N4 :+: m)
- TypeUnary.Vec: instance Eq (Index lim)
- TypeUnary.Vec: instance IsNat Z
- TypeUnary.Vec: instance IsNat n => IsNat (S n)
- TypeUnary.Vec: instance Show (Nat n)
- TypeUnary.Vec: nat :: IsNat n => Nat n
- TypeUnary.Vec: natAdd :: Nat m -> Nat n -> Nat (m :+: n)
- TypeUnary.Vec: natEq :: Nat m -> Nat n -> Maybe (m :=: n)
- TypeUnary.Vec: natIsNat :: Nat n -> (IsNat n => Nat n)
- TypeUnary.Vec: natSucc :: Nat n -> Nat (S n)
- TypeUnary.Vec: natToZ :: Nat n -> Integer
- TypeUnary.Vec: one :: Nat N1
- TypeUnary.Vec: peekV :: (IsNat n, Storable a) => Ptr a -> IO (Vec n a)
- TypeUnary.Vec: pokeV :: (IsNat n, Storable a) => Ptr a -> Vec n a -> IO ()
- TypeUnary.Vec: pureV :: IsNat n => a -> Vec n a
- TypeUnary.Vec: succI :: Index m -> Index (S m)
- TypeUnary.Vec: three :: Nat N3
- TypeUnary.Vec: two :: Nat N2
- TypeUnary.Vec: type N0 = Z
- TypeUnary.Vec: type N1 = S N0
- TypeUnary.Vec: type N10 = S N9
- TypeUnary.Vec: type N11 = S N10
- TypeUnary.Vec: type N12 = S N11
- TypeUnary.Vec: type N13 = S N12
- TypeUnary.Vec: type N14 = S N13
- TypeUnary.Vec: type N15 = S N14
- TypeUnary.Vec: type N16 = S N15
- TypeUnary.Vec: type N2 = S N1
- TypeUnary.Vec: type N3 = S N2
- TypeUnary.Vec: type N4 = S N3
- TypeUnary.Vec: type N5 = S N4
- TypeUnary.Vec: type N6 = S N5
- TypeUnary.Vec: type N7 = S N6
- TypeUnary.Vec: type N8 = S N7
- TypeUnary.Vec: type N9 = S N8
- TypeUnary.Vec: withIsNat :: (IsNat n => Nat n -> a) -> (Nat n -> a)
- TypeUnary.Vec: zero :: Nat N0
+ TypeUnary.Nat: Index :: (n :<: lim) -> (Nat n) -> Index lim
+ TypeUnary.Nat: SLess :: m :<: n -> S m :<: S n
+ TypeUnary.Nat: Succ :: Nat n -> Nat (S n)
+ TypeUnary.Nat: ZLess :: Z :<: S n
+ TypeUnary.Nat: Zero :: Nat Z
+ TypeUnary.Nat: class IsNat n
+ TypeUnary.Nat: data (:<:) m n
+ TypeUnary.Nat: data Index lim
+ TypeUnary.Nat: data Nat :: * -> *
+ TypeUnary.Nat: four :: Nat N4
+ TypeUnary.Nat: index0 :: Index (N1 :+: m)
+ TypeUnary.Nat: index1 :: Index (N2 :+: m)
+ TypeUnary.Nat: index2 :: Index (N3 :+: m)
+ TypeUnary.Nat: index3 :: Index (N4 :+: m)
+ TypeUnary.Nat: instance Eq (Index lim)
+ TypeUnary.Nat: instance IsNat Z
+ TypeUnary.Nat: instance IsNat n => IsNat (S n)
+ TypeUnary.Nat: instance Show (Nat n)
+ TypeUnary.Nat: nat :: IsNat n => Nat n
+ TypeUnary.Nat: natAdd :: Nat m -> Nat n -> Nat (m :+: n)
+ TypeUnary.Nat: natEq :: Nat m -> Nat n -> Maybe (m :=: n)
+ TypeUnary.Nat: natIsNat :: Nat n -> (IsNat n => Nat n)
+ TypeUnary.Nat: natSucc :: Nat n -> Nat (S n)
+ TypeUnary.Nat: natToZ :: Nat n -> Integer
+ TypeUnary.Nat: one :: Nat N1
+ TypeUnary.Nat: succI :: Index m -> Index (S m)
+ TypeUnary.Nat: three :: Nat N3
+ TypeUnary.Nat: two :: Nat N2
+ TypeUnary.Nat: withIsNat :: (IsNat n => Nat n -> a) -> (Nat n -> a)
+ TypeUnary.Nat: zero :: Nat N0
+ TypeUnary.TyNat: data S n
+ TypeUnary.TyNat: data Z
+ TypeUnary.TyNat: type N0 = Z
+ TypeUnary.TyNat: type N1 = S N0
+ TypeUnary.TyNat: type N10 = S N9
+ TypeUnary.TyNat: type N11 = S N10
+ TypeUnary.TyNat: type N12 = S N11
+ TypeUnary.TyNat: type N13 = S N12
+ TypeUnary.TyNat: type N14 = S N13
+ TypeUnary.TyNat: type N15 = S N14
+ TypeUnary.TyNat: type N16 = S N15
+ TypeUnary.TyNat: type N2 = S N1
+ TypeUnary.TyNat: type N3 = S N2
+ TypeUnary.TyNat: type N4 = S N3
+ TypeUnary.TyNat: type N5 = S N4
+ TypeUnary.TyNat: type N6 = S N5
+ TypeUnary.TyNat: type N7 = S N6
+ TypeUnary.TyNat: type N8 = S N7
+ TypeUnary.TyNat: type N9 = S N8

Files

+ src/TypeUnary/Nat.hs view
@@ -0,0 +1,147 @@+{-# LANGUAGE TypeOperators, GADTs, KindSignatures, RankNTypes #-}+{-# OPTIONS_GHC -Wall #-}+----------------------------------------------------------------------+-- |+-- Module      :  TypeUnary.Nat+-- Copyright   :  (c) Conal Elliott 2009+-- License     :  BSD3+-- +-- Maintainer  :  conal@conal.net+-- Stability   :  experimental+-- +-- Experiment in length-typed vectors+----------------------------------------------------------------------++module TypeUnary.Nat+  (+    module TypeUnary.TyNat+  -- * Value-typed natural numbers+  , Nat(..), zero, one, two, three, four+  , withIsNat, natSucc, natIsNat+  , natToZ, natEq, natAdd+  , IsNat(..)+  -- * Inequality proofs and indices+  , (:<:)(..), Index(..), succI, index0, index1, index2, index3+  ) where++import Prelude hiding (foldr,sum)++-- #include "Typeable.h"++import Control.Applicative ((<$>))+import Data.Maybe (isJust)++import Data.Proof.EQ++import TypeUnary.TyNat++-- Natural numbers+data Nat :: * -> * where+  Zero :: Nat Z+  Succ :: IsNat n => Nat n -> Nat (S n)++instance Show (Nat n) where show = show . natToZ++withIsNat :: (IsNat n => Nat n -> a) -> (Nat n -> a)+withIsNat p Zero     = p Zero+withIsNat p (Succ n) = p (Succ n)++-- Helper for when we don't have a convenient proof of IsNat n.+natSucc :: Nat n -> Nat (S n)+natSucc = withIsNat Succ ++natIsNat :: Nat n -> (IsNat n => Nat n)+natIsNat Zero     = Zero+natIsNat (Succ n) = Succ n++{-++-- Another approach (also works):++data NatIsNat :: * -> * where+  NatIsNat :: IsNat n' => Nat n' -> (n :=: n') -> NatIsNat n++natIsNat' :: Nat n -> NatIsNat n+natIsNat' Zero     = NatIsNat Zero Refl+natIsNat' (Succ n) = NatIsNat (Succ n) Refl++withIsNat' :: (IsNat n => Nat n -> a) -> (Nat n -> a)+withIsNat' p n = case natIsNat' n of+                   NatIsNat n' Refl -> p n'+-}++-- | Interpret a 'Nat' as an 'Integer'+natToZ :: Nat n -> Integer+natToZ Zero     = 0+natToZ (Succ n) = (succ . natToZ) n++-- | Equality test+natEq :: Nat m -> Nat n -> Maybe (m :=: n)+Zero   `natEq` Zero   = Just Refl+Succ m `natEq` Succ n = liftEq <$> (m `natEq` n)+_      `natEq` _      = Nothing++-- | Sum of naturals+natAdd :: Nat m -> Nat n -> Nat (m :+: n)+Zero   `natAdd` n = n+Succ m `natAdd` n = natSucc (m `natAdd` n)++zero :: Nat N0+zero = Zero++one :: Nat N1+one = Succ zero++two :: Nat N2+two = Succ one++three :: Nat N3+three = Succ two++four :: Nat N4+four = Succ three+++infix 4 :<:++-- | Proof that @m < n@+data m :<: n where+  ZLess :: Z :<: S n+  SLess :: m :<: n -> S m :<: S n++-- data Index :: * -> * where+--   Index :: (n :<: lim) -> Nat n -> Index lim++-- or++-- | A number under the given limit, with proof+data Index lim = forall n. IsNat n => Index (n :<: lim) (Nat n)++instance Eq (Index lim) where+  Index _ n == Index _ n' = isJust (n `natEq` n')++succI :: Index m -> Index (S m)+succI (Index p n) = Index (SLess p) (Succ n)++index0 :: Index (N1 :+: m)+index0 = Index ZLess Zero++index1 :: Index (N2 :+: m)+index1 = succI index0++index2 :: Index (N3 :+: m)+index2 = succI index1++index3 :: Index (N4 :+: m)+index3 = succI index2++{--------------------------------------------------------------------+    IsNat+--------------------------------------------------------------------}++-- | @n@ a vector length.+class {- Typeable n => -} IsNat n where+  nat    :: Nat n++instance            IsNat Z     where nat = Zero+instance IsNat n => IsNat (S n) where nat = Succ nat
+ src/TypeUnary/TyNat.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE TypeFamilies, TypeOperators, EmptyDataDecls #-}+{-# OPTIONS_GHC -Wall #-}+----------------------------------------------------------------------+-- |+-- Module      :  TypeUnary.TyNat+-- Copyright   :  (c) Conal Elliott 2009+-- License     :  BSD3+-- +-- Maintainer  :  conal@conal.net+-- Stability   :  experimental+-- +-- Type-level unary natural numbers+----------------------------------------------------------------------++module TypeUnary.TyNat+  (+    -- * Type-level natural numbers+    Z, S, (:+:)+  , N0,N1,N2,N3,N4,N5,N6,N7,N8,N9,N10,N11,N12,N13,N14,N15,N16+  ) where+++-- | Type-level representation of zero+data Z+-- | Type-level representation of successor+data S n++-- INSTANCE_TYPEABLE0(Z,zTC ,"Z")+-- INSTANCE_TYPEABLE1(S,sTC ,"S")++infixl 6 :+:++-- | Sum of type-level numbers+type family a :+: b++type instance Z   :+: b = b+type instance S a :+: b = S (a :+: b)++-- Generated code+-- +--   putStrLn $ unlines ["type N" ++ show (n+1) ++ " = S N" ++ show n | n <- [0..15]]++type N0  = Z+type N1  = S N0+type N2  = S N1+type N3  = S N2+type N4  = S N3+type N5  = S N4+type N6  = S N5+type N7  = S N6+type N8  = S N7+type N9  = S N8+type N10 = S N9+type N11 = S N10+type N12 = S N11+type N13 = S N12+type N14 = S N13+type N15 = S N14+type N16 = S N15
src/TypeUnary/Vec.hs view
@@ -21,23 +21,16 @@  module TypeUnary.Vec   (-  -- * Type-level numbers-    Z, S, (:+:)-  , N0,N1,N2,N3,N4,N5,N6,N7,N8,N9,N10,N11,N12,N13,N14,N15,N16-  -- * Typed natural numbers-  , Nat(..), zero, one, two, three, four-  , withIsNat, natSucc, natIsNat-  , natToZ, natEq, natAdd, (:<:)-  , Index(..), succI, index0, index1, index2, index3+    module TypeUnary.Nat   -- * Vectors-  , Vec(..), headV, tailV, joinV, IsNat(..), (<+>), indices+  , Vec(..), headV, tailV, joinV, (<+>), indices   , Vec0,Vec1,Vec2,Vec3,Vec4,Vec5,Vec6,Vec7,Vec8,Vec9   , Vec10,Vec11,Vec12,Vec13,Vec14,Vec15,Vec16   , vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8   , un1, un2, un3, un4   , get, get0, get1, get2, get3   , set, set0, set1, set2, set3-  , swizzle, split, deleteV+  , swizzle, split, deleteV, elemsV   , ToVec(..)   ) where @@ -48,7 +41,6 @@ import Control.Applicative (Applicative(..),liftA2,(<$>)) import Data.Foldable (Foldable(..),toList,sum) import Data.Traversable (Traversable(..))-import Data.Maybe (isJust) -- import Data.Typeable  import Foreign.Storable@@ -56,153 +48,7 @@  import Data.VectorSpace -import Data.Proof.EQ---{---------------------------------------------------------------------    Type-level numbers---------------------------------------------------------------------}---- | Type-level representation of zero-data Z--- | Type-level representation of successor-data S n---- INSTANCE_TYPEABLE0(Z,zTC ,"Z")--- INSTANCE_TYPEABLE1(S,sTC ,"S")--infixl 6 :+:---- | Sum of type-level numbers-type family a :+: b--type instance Z   :+: b = b-type instance S a :+: b = S (a :+: b)--type N0  = Z-type N1  = S N0-type N2  = S N1-type N3  = S N2-type N4  = S N3-type N5  = S N4-type N6  = S N5-type N7  = S N6-type N8  = S N7-type N9  = S N8-type N10 = S N9-type N11 = S N10-type N12 = S N11-type N13 = S N12-type N14 = S N13-type N15 = S N14-type N16 = S N15---- putStrLn $ unlines ["type N" ++ show (n+1) ++ " = S N" ++ show n | n <- [0..15]]--{---------------------------------------------------------------------    Typed natural numbers---------------------------------------------------------------------}---- Natural numbers-data Nat :: * -> * where-  Zero :: Nat Z-  Succ :: IsNat n => Nat n -> Nat (S n)--instance Show (Nat n) where show = show . natToZ--withIsNat :: (IsNat n => Nat n -> a) -> (Nat n -> a)-withIsNat p Zero     = p Zero-withIsNat p (Succ n) = p (Succ n)---- Helper for when we don't have a convenient proof of IsNat n.-natSucc :: Nat n -> Nat (S n)-natSucc = withIsNat Succ --natIsNat :: Nat n -> (IsNat n => Nat n)-natIsNat Zero     = Zero-natIsNat (Succ n) = Succ n--{----- Another approach (also works):--data NatIsNat :: * -> * where-  NatIsNat :: IsNat n' => Nat n' -> (n :=: n') -> NatIsNat n--natIsNat' :: Nat n -> NatIsNat n-natIsNat' Zero     = NatIsNat Zero Refl-natIsNat' (Succ n) = NatIsNat (Succ n) Refl--withIsNat' :: (IsNat n => Nat n -> a) -> (Nat n -> a)-withIsNat' p n = case natIsNat' n of-                   NatIsNat n' Refl -> p n'--}---- | Interpret a 'Nat' as an 'Integer'-natToZ :: Nat n -> Integer-natToZ Zero     = 0-natToZ (Succ n) = (succ . natToZ) n---- | Equality test-natEq :: Nat m -> Nat n -> Maybe (m :=: n)-Zero   `natEq` Zero   = Just Refl-Succ m `natEq` Succ n = liftEq <$> (m `natEq` n)-_      `natEq` _      = Nothing---- | Sum of naturals-natAdd :: Nat m -> Nat n -> Nat (m :+: n)-Zero   `natAdd` n = n-Succ m `natAdd` n = natSucc (m `natAdd` n)--zero :: Nat N0-zero = Zero--one :: Nat N1-one = Succ zero--two :: Nat N2-two = Succ one--three :: Nat N3-three = Succ two--four :: Nat N4-four = Succ three---infix 4 :<:---- | Proof that @m < n@-data m :<: n where-  ZLess :: Z :<: S n-  SLess :: m :<: n -> S m :<: S n---- data Index :: * -> * where---   Index :: (n :<: lim) -> Nat n -> Index lim---- or---- | A number under the given limit, with proof-data Index lim = forall n. IsNat n => Index (n :<: lim) (Nat n)--instance Eq (Index lim) where-  Index _ n == Index _ n' = isJust (n `natEq` n')--succI :: Index m -> Index (S m)-succI (Index p n) = Index (SLess p) (Succ n)--index0 :: Index (N1 :+: m)-index0 = Index ZLess Zero--index1 :: Index (N2 :+: m)-index1 = succI index0--index2 :: Index (N3 :+: m)-index2 = succI index1--index3 :: Index (N4 :+: m)-index3 = succI index2-+import TypeUnary.Nat  {--------------------------------------------------------------------     Vectors@@ -283,6 +129,13 @@   pure  = pureV   (<*>) = applyV +pureV :: IsNat n => a -> Vec n a+pureV = pureV' nat++pureV' :: Nat n -> a -> Vec n a+pureV' Zero     _ = ZVec+pureV' (Succ n) a = a :< pureV' n a+ applyV :: Vec n (a -> b) -> Vec n a -> Vec n b ZVec      `applyV` ZVec      = ZVec (f :< fs) `applyV` (x :< xs) = f x :< (fs `applyV` xs)@@ -332,32 +185,36 @@    peek      = peekV . castPtr    poke      = pokeV . castPtr -{---------------------------------------------------------------------    IsNat---------------------------------------------------------------------} -instance IsNat Z where-  nat          = Zero-  pureV _      = ZVec-  elemsV []    = ZVec-  elemsV (_:_) = error "elemsV: too many elements"-  peekV        = const (return ZVec)-  pokeV        = const (const (return ()))+infixl 1 <+>+-- | Concatenation of vectors+(<+>) :: Vec m a -> Vec n a -> Vec (m :+: n) a+ZVec     <+> v = v+(a :< u) <+> v = a :< (u <+> v) -instance IsNat n => IsNat (S n) where-  nat               = Succ nat-  pureV a           = a :< pureV a-  elemsV []         = error "elemsV: too few elements"-  elemsV (a : as)   = a :< elemsV as-  peekV p           =  do a  <- peek p-                          as <- peekV (p `plusPtr` sizeOf a)-                          return (a :< as)-                     -- liftA2 (:<) (peek p) (peekV (succPtr p))-  -- peekV = (liftA2.liftA2) (:<) peek (peekV . succPtr)-  -- TODO: Try these niftier peekV definitions-  pokeV p (a :< as) = do poke p a-                         pokeV (p `plusPtr` sizeOf a) as +peekV :: (IsNat n, Storable a) => Ptr a -> IO (Vec n a)+peekV = peekV' nat++pokeV :: (IsNat n, Storable a) => Ptr a -> Vec n a -> IO ()+pokeV = pokeV' nat++peekV' :: Storable a => Nat n -> Ptr a -> IO (Vec n a)+peekV' Zero _ = return ZVec+peekV' (Succ n) p =  do a  <- peek p+                        as <- peekV' n (p `plusPtr` sizeOf a)+                        return (a :< as)++-- peekV' (Succ n) p = liftA2 (:<) (peek p) (peekV (succPtr p))+--                   = liftA2 (:<) peek (peekV (succPtr p))+-- +-- peekV' (Succ _) = (liftA2.liftA2) (:<) peek (peekV . succPtr)++pokeV' :: Storable a => Nat n -> Ptr a -> Vec n a -> IO ()+pokeV' Zero     _ ZVec      = return ()+pokeV' (Succ n) p (a :< as) = do poke p a+                                 pokeV' n (p `plusPtr` sizeOf a) as+ -- -- Experiment toward simplifying away the plusPtr calls. -- succPtr :: forall a. Storable a => Ptr a -> Ptr a -- succPtr p = p `plusPtr` sizeOf (undefined :: a)@@ -365,12 +222,6 @@ -- TODO: Optimize peekV, pokeV.  For instance, unroll the loop in the -- dictionary, remove the sizeOf dependence on @a@. -infixl 1 <+>--- | Concatenation of vectors-(<+>) :: Vec m a -> Vec n a -> Vec (m :+: n) a-ZVec     <+> v = v-(a :< u) <+> v = a :< (u <+> v)- -- | Indices under @n@: 'index0' :< 'index1' :< ... indices :: Nat n -> Vec n (Index n) indices Zero     = ZVec@@ -379,28 +230,9 @@ -- TODO: Try reimplementing many Vec functions via foldr.  Warning: some -- (most?) will fail because they rely on a polymorphic combining function. --- | @n@ a vector length.-class {- Typeable n => -} IsNat n where-  nat    :: Nat n-  pureV  :: a   -> Vec n a-  elemsV :: [a] -> Vec n a-  peekV  :: Storable a => Ptr a -> IO (Vec n a)-  pokeV  :: Storable a => Ptr a -> Vec n a -> IO ()- -- Convert from vector to list via Data.Foldable.toList -{---- TODO: remove all but nat from the class. Define the rest outside of the--- class by using nat. Then break this module into Nat and Vec. For instance, -pureV :: IsNat n => a -> Vec n a-pureV = pureN nat--pureN :: Nat n -> a -> Vec n a-pureN Zero     _ = ZVec-pureN (Succ n) a = a :< pureN n a--}- -- Convenient nicknames  type Vec0  = Vec N0@@ -575,6 +407,17 @@ deleteV b (a :< as) | a == b = as deleteV _ (_ :< ZVec)        = error "deleteV: did not find element" deleteV b (a :< as@(_:<_))   = a :< deleteV b as+++-- | Convert a list into a vector. Error if the list is too short or too long+elemsV :: IsNat n => [a] -> Vec n a+elemsV = elemsV' nat++elemsV' :: Nat n -> [a] -> Vec n a+elemsV' Zero []           = ZVec+elemsV' Zero (_:_)        = error "elemsV: too many elements"+elemsV' (Succ _) []       = error "elemsV: too few elements"+elemsV' (Succ n) (a : as) = a :< elemsV' n as   {--------------------------------------------------------------------
type-unary.cabal view
@@ -1,5 +1,5 @@ Name:                type-unary-Version:             0.1.9+Version:             0.1.10 Cabal-Version:       >= 1.2 Synopsis:               Type-level and typed unary natural numbers, vectors, inequality proofs@@ -21,7 +21,10 @@   hs-Source-Dirs:      src   Extensions:   Build-Depends:       base >=4 && < 5, ty, vector-space-  Exposed-Modules:     TypeUnary.Vec+  Exposed-Modules:     +                       TypeUnary.TyNat+                       TypeUnary.Nat+                       TypeUnary.Vec                           ghc-options:         -Wall