flip Vec arguments to allow a Functor instance

This commit is contained in:
rnhmjoj 2016-12-04 04:16:07 +01:00
parent c7ac8bb7a7
commit d22f298356
No known key found for this signature in database
GPG Key ID: 362BB82B7E496B7C
2 changed files with 76 additions and 58 deletions

View File

@ -13,14 +13,21 @@ module Data.TypeClass
, Read(..) , Read(..)
, IsList(..) , IsList(..)
, IsString(..) , IsString(..)
, Functor(..)
, Applicative(..)
, Monad(..)
) where ) where
import GHC.Enum import GHC.Enum
import GHC.Show import GHC.Show
import GHC.Read import GHC.Read
import GHC.Num import GHC.Num
import GHC.Real
import GHC.Exts import GHC.Exts
import Prelude (Eq(..), Ord(..), Integral(..)) import Data.Eq
import Data.Ord
import Data.Functor
import Prelude (Monad(..), Applicative(..))
-- * Aliases -- * Aliases

View File

@ -23,7 +23,7 @@ import Data.Nat hiding ((+), (-), (×), min, max)
import Data.Bool import Data.Bool
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Char (Char) import Data.Char (Char)
import Data.Function (()) import Data.Function ((), flip)
import Data.Singletons (SingI, sing) import Data.Singletons (SingI, sing)
import Data.TypeClass import Data.TypeClass
@ -32,34 +32,35 @@ import Data.TypeClass
infixr 5 :- infixr 5 :-
-- | The 'Vec' datatype -- | The 'Vec' datatype
data Vec Type Type where data Vec Type Type where
Nil Vec a Z -- ^ empty 'Vec', length 0 Nil Vec Z a -- ^ empty 'Vec', length 0
(:-) a Vec a n Vec a (S n) -- ^ "cons" operator (:-) a Vec n a Vec (S n) a -- ^ "cons" operator
-- | 'String' type alias for vector of characters -- | 'String' type alias for vector of characters
type String n = Vec Char n type String n = Vec n Char
deriving instance Eq a Eq (Vec a n) deriving instance Eq a Eq (Vec n a)
instance Show a Show (Vec a n) where instance Show a Show (Vec n a) where
showsPrec d = showsPrec d vecToList showsPrec d = showsPrec d vecToList
instance SingI n IsList (Vec a n) where instance SingI n IsList (Vec n a) where
type Item (Vec a n) = a type Item (Vec n a) = a
fromList = listToVec fromList = listToVec
toList = vecToList toList = vecToList
instance SingI n IsString (String n) where instance SingI n IsString (String n) where
fromString = fromList fromString = fromList
instance SingI n Functor (Vec n) where
fmap = map
-- * Conversions -- * Conversions
-- | Convert a 'Vec' into a List -- | Convert a 'Vec' into a List
vecToList Vec a n [a] vecToList Vec n a [a]
vecToList Nil = [] vecToList Nil = []
vecToList (x :- xs) = x : vecToList xs vecToList (x :- xs) = x : vecToList xs
@ -69,10 +70,10 @@ vecToList (x :- xs) = x : vecToList xs
-- It's not possible to convert an infinite list to a vector -- It's not possible to convert an infinite list to a vector
-- as haskell does not permit constructing infinite type, -- as haskell does not permit constructing infinite type,
-- which the resulting vector length would be. -- which the resulting vector length would be.
listToVec SingI n [a] Vec a n listToVec SingI n [a] Vec n a
listToVec = f sing listToVec = f sing
where f S n [a] Vec a n where f S n [a] Vec n a
f SZ _ = Nil f SZ [] = Nil
f (SS n) (x:xs) = x :- f n xs f (SS n) (x:xs) = x :- f n xs
@ -80,31 +81,31 @@ listToVec = f sing
-- * Basic functions -- * Basic functions
-- | Vector concatenation -- | Vector concatenation
() Vec a n Vec a m Vec a (n :+ m) () Vec n a Vec m a Vec (n :+ m) a
() (x :- xs) ys = x :- xs ys () (x :- xs) ys = x :- xs ys
() Nil ys = ys () Nil ys = ys
-- | Extracts the 'head' (ie the first element) of a nonempty 'Vec'. -- | Extracts the 'head' (ie the first element) of a nonempty 'Vec'.
head Vec a (S n) a head Vec (S n) a a
head (x :- _) = x head (x :- _) = x
-- | Extracts the last element of a nonempty 'Vec'. -- | Extracts the last element of a nonempty 'Vec'.
last Vec a (S n) a last Vec (S n) a a
last (x :- Nil) = x last (x :- Nil) = x
last (x :- y :- ys) = last (y :- ys) last (x :- y :- ys) = last (y :- ys)
-- | Applied to a nonempty 'Vec' returns everything but its first element. -- | Applied to a nonempty 'Vec' returns everything but its first element.
-- > x ≡ head x ⧺ tail x -- > x ≡ head x ⧺ tail x
tail Vec a (S n) Vec a n tail Vec (S n) a Vec n a
tail (_ :- xs) = xs tail (_ :- xs) = xs
-- | Applied to a nonempty 'Vec' returns everything but its last element. -- | Applied to a nonempty 'Vec' returns everything but its last element.
-- > x ≡ init x ⧺ last x -- > x ≡ init x ⧺ last x
init Vec a (S n) Vec a n init Vec (S n) a Vec n a
init (x :- Nil) = Nil init (x :- Nil) = Nil
init (x :- y :- ys) = x :- init (y :- ys) init (x :- y :- ys) = x :- init (y :- ys)
@ -112,23 +113,23 @@ init (x :- y :- ys) = x :- init (y :- ys)
-- | Given a nonempty 'Vec' returns the first element -- | Given a nonempty 'Vec' returns the first element
-- and the rest of the vector in a tuple. -- and the rest of the vector in a tuple.
-- > uncons x ≡ (head x, tail x) -- > uncons x ≡ (head x, tail x)
uncons Vec a (S n) (a, Vec a n) uncons Vec (S n) a (a, Vec n a)
uncons (x :- xs) = (x, xs) uncons (x :- xs) = (x, xs)
-- | Test whether a 'Vec' has zero length. -- | Test whether a 'Vec' has zero length.
null Vec a n 𝔹 null Vec n a 𝔹
null Nil = T null Nil = T
null _ = F null _ = F
-- | Returns the length (numbers of elements) of a 'Vec'. -- | Returns the length (numbers of elements) of a 'Vec'.
length Vec a n length Vec n a
length Nil = Z length Nil = Z
length (_ :- xs) = S (length xs) length (_ :- xs) = S (length xs)
-- | Same as 'length' but produces a singleton type 'S'. -- | Same as 'length' but produces a singleton type 'S'.
sLength Vec a n S n sLength Vec n a S n
sLength Nil = SZ sLength Nil = SZ
sLength (x :- xs) = SS (sLength xs) sLength (x :- xs) = SS (sLength xs)
@ -137,14 +138,14 @@ sLength (x :- xs) = SS (sLength xs)
-- * Transformations -- * Transformations
-- | Applies a function on every element of a 'Vec'. -- | Applies a function on every element of a 'Vec'.
map (a b) Vec a n Vec b n map (a b) Vec n a Vec n b
map _ Nil = Nil map _ Nil = Nil
map f (x :- xs) = f x :- map f xs map f (x :- xs) = f x :- map f xs
-- | Reverse the order of the elements of a 'Vec' -- | Reverse the order of the elements of a 'Vec'
-- > reverse ∘ reverse = id -- > reverse ∘ reverse = id
reverse Vec a n Vec a n reverse Vec n a Vec n a
reverse Nil = Nil reverse Nil = Nil
reverse (y :- ys) = gcastWith proof (reverse ys (y :- Nil)) reverse (y :- ys) = gcastWith proof (reverse ys (y :- Nil))
where proof = succ_plus (sLength ys) where proof = succ_plus (sLength ys)
@ -153,7 +154,7 @@ reverse (y :- ys) = gcastWith proof (reverse ys ⧺ (y :- Nil))
-- | 'intersperse' @s@ takes a 'Vec' and produces one where -- | 'intersperse' @s@ takes a 'Vec' and produces one where
-- @s@ is interspersed (ie inserted between) every two elements -- @s@ is interspersed (ie inserted between) every two elements
-- of the vector -- of the vector
intersperse a Vec a n Vec a (n :+ Pred n) intersperse a Vec n a Vec (n :+ Pred n) a
intersperse _ Nil = Nil intersperse _ Nil = Nil
intersperse _ (x :- Nil) = x :- Nil intersperse _ (x :- Nil) = x :- Nil
intersperse s (x :- xs) = gcastWith proof (x :- s :- intersperse s xs) intersperse s (x :- xs) = gcastWith proof (x :- s :- intersperse s xs)
@ -165,7 +166,7 @@ intersperse s (x :- xs) = gcastWith proof (x :- s :- intersperse s xs)
-- | 'intercalate' @xs xss@ is equivalent to -- | 'intercalate' @xs xss@ is equivalent to
-- @('concat' ('intersperse' xs xss))@. It inserts the vector @xs@ -- @('concat' ('intersperse' xs xss))@. It inserts the vector @xs@
-- in between the vectors in @xss@ and concatenates the result. -- in between the vectors in @xss@ and concatenates the result.
intercalate Vec a n Vec (Vec a n) m Vec a ((m :+ Pred m) :× n) intercalate Vec n a Vec m (Vec n a) Vec ((m :+ Pred m) :× n) a
intercalate xs xss = concat (intersperse xs xss) intercalate xs xss = concat (intersperse xs xss)
@ -174,7 +175,7 @@ intercalate xs xss = concat (intersperse xs xss)
-- --
-- > transpose [[1,2,3],[4,5,6]] ≡ [[1,4],[2,5],[3,6]] -- > transpose [[1,2,3],[4,5,6]] ≡ [[1,4],[2,5],[3,6]]
-- --
transpose SingI n Vec (Vec a n) m Vec (Vec a m) n transpose SingI n Vec m (Vec n a) Vec n (Vec m a)
transpose Nil = replicate Nil transpose Nil = replicate Nil
transpose (xs :- xss) = gcastWith proof (zipWith (:-) xs (transpose xss)) transpose (xs :- xss) = gcastWith proof (zipWith (:-) xs (transpose xss))
where proof = min_self (sLength xs) where proof = min_self (sLength xs)
@ -183,12 +184,12 @@ transpose (xs :- xss) = gcastWith proof (zipWith (:-) xs (transpose xss))
-- | The 'permutations' function returns the vector of all permutations of the argument. -- | The 'permutations' function returns the vector of all permutations of the argument.
-- --
-- > permutations "abc" ≡ ["abc","bac","cba","bca","cab","acb"] -- > permutations "abc" ≡ ["abc","bac","cba","bca","cab","acb"]
permutations Vec a n Vec (Vec a n) (Fact n) permutations Vec n a Vec (Fact n) (Vec n a)
permutations Nil = Nil:-Nil permutations Nil = Nil:-Nil
permutations (x:-Nil) = (x:-Nil):-Nil permutations (x:-Nil) = (x:-Nil):-Nil
permutations xs@(_:-_) = concatMap (\(y,ys) map (y:-) (permutations ys)) (select xs) permutations xs@(_:-_) = concatMap (\(y,ys) map (y:-) (permutations ys)) (select xs)
where where
select Vec a n Vec (a, Vec a (Pred n)) n select Vec n a Vec n (a, Vec (Pred n) a)
select Nil = Nil select Nil = Nil
select (x:-Nil) = (x, Nil) :- Nil select (x:-Nil) = (x, Nil) :- Nil
select (x:-xs@(_:-_)) = (x,xs) :- map (\(y,ys) (y, x:-ys)) (select xs) select (x:-xs@(_:-_)) = (x,xs) :- map (\(y,ys) (y, x:-ys)) (select xs)
@ -197,27 +198,27 @@ permutations xs@(_:-_) = concatMap (\(y,ys) → map (y:-) (permutations ys)) (se
-- | 'foldl' applied to a binary operator, a starting value -- | 'foldl' applied to a binary operator, a starting value
-- and a 'Vec' reduces the vector to a single value obtained -- and a 'Vec' reduces the vector to a single value obtained
-- by sequentially applying the operation from the left to the right. -- by sequentially applying the operation from the left to the right.
foldl (a b a) a Vec b n a foldl (a b a) a Vec n b a
foldl _ x Nil = x foldl _ x Nil = x
foldl () x (y :- ys) = foldl () (x y) ys foldl () x (y :- ys) = foldl () (x y) ys
-- | Same as "fold" but reduces the vector in the opposite -- | Same as "fold" but reduces the vector in the opposite
-- direction: from the right to the left. -- direction: from the right to the left.
foldr (a b b) b Vec a n b foldr (a b b) b Vec n a b
foldr _ x Nil = x foldr _ x Nil = x
foldr () x (y:-ys) = y (foldr () x ys) foldr () x (y:-ys) = y (foldr () x ys)
-- | Variant of 'foldl' which requires no starting value but -- | Variant of 'foldl' which requires no starting value but
-- applies only on nonempty 'Vec' -- applies only on nonempty 'Vec'
foldl (a a a) Vec a (S n) a foldl (a a a) Vec (S n) a a
foldl _ (x :- Nil) = x foldl _ (x :- Nil) = x
foldl () (x :- y :- ys) = foldl () (x y :- ys) foldl () (x :- y :- ys) = foldl () (x y :- ys)
-- | As for 'foldl', a variant of 'foldr' with no starting point -- | As for 'foldl', a variant of 'foldr' with no starting point
foldr (a a a) Vec a (S n) a foldr (a a a) Vec (S n) a a
foldr _ (x :- Nil) = x foldr _ (x :- Nil) = x
foldr () (x :- y :- ys) = x (foldr () (y :- ys)) foldr () (x :- y :- ys) = x (foldr () (y :- ys))
@ -226,7 +227,7 @@ foldr₁ (⊗) (x :- y :- ys) = x ⊗ (foldr₁ (⊗) (y :- ys))
-- * Special folds -- * Special folds
-- | The concatenation of all the elements of a vector of vectors. -- | The concatenation of all the elements of a vector of vectors.
concat Vec (Vec a n) m Vec a (m :× n) concat Vec m (Vec n a) Vec (m :× n) a
concat Nil = Nil concat Nil = Nil
concat (xs :- xss) = gcastWith proof (xs concat xss) concat (xs :- xss) = gcastWith proof (xs concat xss)
where where
@ -237,61 +238,61 @@ concat (xs :- xss) = gcastWith proof (xs ⧺ concat xss)
-- | Map a function over all the elements of a vector and concatenate -- | Map a function over all the elements of a vector and concatenate
-- the resulting vectors. -- the resulting vectors.
concatMap (a Vec b n) Vec a m Vec b (m :× n) concatMap (a Vec n b) Vec m a Vec (m :× n) b
concatMap f = concat map f concatMap f = concat map f
-- | Applied to a a value produces a vector obtained by -- | Applied to a a value produces a vector obtained by
-- duplicating the value @n@ times. -- duplicating the value @n@ times.
replicate a n. SingI n a Vec a n replicate a n. SingI n a Vec n a
replicate = replicate' (sing S n) replicate = replicate' (sing S n)
-- | 'replicate' variant with an explicit length argument. -- | 'replicate' variant with an explicit length argument.
replicate' S n a Vec a n replicate' S n a Vec n a
replicate' SZ _ = Nil replicate' SZ _ = Nil
replicate' (SS n) a = a :- replicate' n a replicate' (SS n) a = a :- replicate' n a
-- | 'and' returns the conjunction of a container of bools. -- | 'and' returns the conjunction of a container of bools.
and Vec 𝔹 (S n) 𝔹 and Vec (S n) 𝔹 𝔹
and = foldr () and = foldr ()
-- | 'or' returns the disjunction of a container of bools. -- | 'or' returns the disjunction of a container of bools.
or Vec 𝔹 (S n) 𝔹 or Vec (S n) 𝔹 𝔹
or = foldr () or = foldr ()
-- | Determines whether any element of the structure satisfies the predicate. -- | Determines whether any element of the structure satisfies the predicate.
any (a 𝔹) Vec a n 𝔹 any (a 𝔹) Vec n a 𝔹
any _ Nil = F any _ Nil = F
any p (x :- xs) = or (map p (x :- xs)) any p (x :- xs) = or (map p (x :- xs))
-- | Determines whether all elements of the structure satisfy the predicate. -- | Determines whether all elements of the structure satisfy the predicate.
all (a 𝔹) Vec a n 𝔹 all (a 𝔹) Vec n a 𝔹
all _ Nil = T all _ Nil = T
all p (x :- xs) = and (map p (x :- xs)) all p (x :- xs) = and (map p (x :- xs))
-- | The least element of a vector. -- | The least element of a vector.
minimum Ord a Vec a (S n) a minimum Ord a Vec (S n) a a
minimum = foldr min minimum = foldr min
-- | The largest element of a vector. -- | The largest element of a vector.
maximum Ord a Vec a (S n) a maximum Ord a Vec (S n) a a
maximum = foldr max maximum = foldr max
-- | The 'sum' function computes the sum of the numbers of a vector. -- | The 'sum' function computes the sum of the numbers of a vector.
sum Num a Vec a n a sum Num a Vec n a a
sum = foldr (+) 0 sum = foldr (+) 0
-- | The 'product' function computes the product of the numbers of a vector. -- | The 'product' function computes the product of the numbers of a vector.
product Num a Vec a n a product Num a Vec n a a
product = foldr (×) 1 product = foldr (×) 1
@ -299,23 +300,23 @@ product = foldr (×) 1
-- Extracting subvectors -- Extracting subvectors
-- | 'take' returns the first @n@ element of the vector -- | 'take' returns the first @n@ element of the vector
take a n m. SingI n Vec a m Vec a n take a n m. SingI n Vec m a Vec n a
take = take' (sing S n) take = take' (sing S n)
-- | Variant of 'take' with an explicit argument. -- | Variant of 'take' with an explicit argument.
take' S n Vec a m Vec a n take' S n Vec m a Vec n a
take' SZ _ = Nil take' SZ _ = Nil
take' (SS n) (x :- xs) = x :- take' n xs take' (SS n) (x :- xs) = x :- take' n xs
-- | 'drop' returns every element of the vector but the first @n@ -- | 'drop' returns every element of the vector but the first @n@
drop a n m. SingI n Vec a m Vec a (m :- n) drop a n m. SingI n Vec m a Vec (m :- n) a
drop = drop' (sing S n) drop = drop' (sing S n)
-- | Variant of 'drop' with an explicit argument. -- | Variant of 'drop' with an explicit argument.
drop' S n Vec a m Vec a (m :- n) drop' S n Vec m a Vec (m :- n) a
drop' SZ x = x drop' SZ x = x
drop' (SS n) (x :- xs) = drop' n xs drop' (SS n) (x :- xs) = drop' n xs
@ -324,18 +325,28 @@ drop' (SS n) (x :- xs) = drop' n xs
-- Searching by equality -- Searching by equality
-- | Does the element occur in the structure? -- | Does the element occur in the structure?
elem Eq a Vec a n a 𝔹 elem Eq a Vec n a a 𝔹
elem Nil _ = F elem Nil _ = F
elem (x :- xs) y = (x y) (elem xs y) elem (x :- xs) y = (x y) (elem xs y)
-- | Infix version of 'elem'
() Eq a a Vec n a 𝔹
() = flip elem
-- | 'notElem' is the negation of 'elem'. -- | 'notElem' is the negation of 'elem'.
notElem Eq a Vec a n a 𝔹 notElem Eq a Vec n a a 𝔹
notElem xs = (¬) elem xs notElem xs = (¬) elem xs
-- | Infix version of 'notElem'
() Eq a a Vec n a 𝔹
() = flip notElem
-- | 'lookup' key assocs looks up a key in an association vector. -- | 'lookup' key assocs looks up a key in an association vector.
lookup Eq a a Vec (a, b) n Maybe b lookup Eq a a Vec n (a, b) Maybe b
lookup t Nil = Nothing lookup t Nil = Nothing
lookup t ((k,v) :- x) = lookup t ((k,v) :- x) =
if t k if t k
@ -352,7 +363,7 @@ lookup t ((k,v) :- x) =
-- 'zip' is right-lazy: -- 'zip' is right-lazy:
-- --
-- > zip Nil ⊥ ≡ Nil -- > zip Nil ⊥ ≡ Nil
zip Vec a n Vec b m Vec (a, b) (Min n m) zip Vec n a Vec m b Vec (Min n m) (a, b)
zip = zipWith (,) zip = zipWith (,)
@ -364,7 +375,7 @@ zip = zipWith (,)
-- 'zipWith' is right-lazy: -- 'zipWith' is right-lazy:
-- --
-- > zipWith f Nil ⊥ ≡ Nil -- > zipWith f Nil ⊥ ≡ Nil
zipWith (a b c) Vec a n Vec b m Vec c (Min n m) zipWith (a b c) Vec n a Vec m b Vec (Min n m) c
zipWith _ Nil _ = Nil zipWith _ Nil _ = Nil
zipWith _ _ Nil = Nil zipWith _ _ Nil = Nil
zipWith () (x :- xs) (y :- ys) = x y :- zipWith () xs ys zipWith () (x :- xs) (y :- ys) = x y :- zipWith () xs ys
@ -372,7 +383,7 @@ zipWith (⊗) (x :- xs) (y :- ys) = x ⊗ y :- zipWith (⊗) xs ys
-- | 'unzip' transforms a vectors of pairs into a vector of first components -- | 'unzip' transforms a vectors of pairs into a vector of first components
-- and a vector of second components. -- and a vector of second components.
unzip Vec (a, b) n (Vec a n, Vec b n) unzip Vec n (a, b) (Vec n a, Vec n b)
unzip Nil = (Nil, Nil) unzip Nil = (Nil, Nil)
unzip ((x, y) :- xys) = (x :- xs, y :- ys) unzip ((x, y) :- xys) = (x :- xs, y :- ys)
where (xs, ys) = unzip xys where (xs, ys) = unzip xys