tuple-sop-0.3.1.0: functions on n-ary tuples using generics-sop

Safe HaskellNone
LanguageHaskell2010

Data.Tuple.Ops

Contents

Description

This module exports various functions that work with n-ary tuples.

Generally speaking all functions can be applied to tuples of different sizes.

However, to improve type inference we have limited our implementation to only only work on tuples of at most size 10.

For functions working with indexes we have also added some convenience functions to avoid usage of Proxy's.

Synopsis

Selection

sel :: Select s t => s -> t Source #

Takes an n-ary tuple and returns the first element of the requested type

>>> sel (1,'d','c') :: Char
'd'

selN :: SelectN s n t => s -> Proxy n -> t Source #

Takes an n-ary tuple and a Proxy carrying a Nat, returns the element with the index specified by the Nat

>>> selN (1,'d',False,'c') (Proxy :: Proxy 2)
False

convenience functions

sel1 :: SelectN s 0 t => s -> t Source #

Selects the first element in an n-ary tuple

>>> sel1 (0,'d','c')
0

sel2 :: SelectN s 1 t => s -> t Source #

sel3 :: SelectN s 2 t => s -> t Source #

sel4 :: SelectN s 3 t => s -> t Source #

sel5 :: SelectN s 4 t => s -> t Source #

sel6 :: SelectN s 5 t => s -> t Source #

sel7 :: SelectN s 6 t => s -> t Source #

sel8 :: SelectN s 7 t => s -> t Source #

sel9 :: SelectN s 8 t => s -> t Source #

sel10 :: SelectN s 9 t => s -> t Source #

lastT :: forall s n t. (LengthT s ~ n, SelectN s (n - 1) t) => s -> t Source #

Selects the last element of any n-ary tuple

>>> lastT (1,2,3,4)
4
>>> lastT (1,2,3)
3

Application

app :: App f s t => f -> s -> t Source #

Applies a monomorphic function to the first element of an n-ary tuple that matches the type of the argument of the function.

>>> app not ('d',True)
('d',False)

Sometimes it is necessary to specify the result type, such that the function becomes monomorphic >>> app (+1) (True,5) :: (Bool,Integer) (True,6)

One may also use appPoly, which doesn't require specifying the result type. However it can only apply functions to the first element of an n-ary tuple.

appPoly :: App (Poly a b) s t => (a -> b) -> s -> t Source #

Applies a polymorphic function to the first element of an n-ary tuple. Since the function is polymorphic in its argument it can always be applied to the first element of a tuple.

>>> appPoly show (5,False)
("5",False)

appN :: AppN f s n t => f -> s -> Proxy n -> t Source #

Applies a function to the element at index n in an n-ary tuple.

>>> appN not (Proxy 2) (False,True,False)
(False,True,True)

appN also works for polymorphic functions

>>> appN show (5,'c',False) (Proxy :: Proxy 2)
(5,'c',"False")

appF :: AppF f s t => f -> s -> t Source #

Apply an n-ary function to an n-ary tuple. The function takes an argument for each component of the tuple in left-to-right order.

>>> appF (\a b c -> if a then b else c) (False,1,2)
2

mapT :: MapT f s t => f -> s -> t Source #

Maps a monomorphic function over each element in an n-ary tuple that matches the type of the argument of the function

>>> mapT not (True,'c',False)
(False,'c',True)

Sometimes it is necessary to specify the result type.

>>> mapT (+1) (5,6,7,False) :: (Integer,Integer,Integer,Bool)
(6,7,8,False)

Using mapPolyT this is not necessary. However, to use mapPolyT the tuple may only contains elements of a single type.

mapPolyT :: MapT (Poly a b) s t => (a -> b) -> s -> t Source #

Applies a polymorphic function to each element in an n-ary tuple. Requires all elements in the tuple to be of the same type.

>>> mapPolyT (+1) (5,6,7,8)
(6,7,8,9)
>>> mapPolyT (+1) (5,6,7,False)
No instance for (Num Bool) arising from the literal `5'

convenience functions

app1 :: AppN f s 0 t => f -> s -> t Source #

Applies a function to the first element of an n-ary tuple

>>> app1 (+1) (5,6,7)
(6,6,7)

app2 :: AppN f s 1 t => f -> s -> t Source #

app3 :: AppN f s 2 t => f -> s -> t Source #

app4 :: AppN f s 3 t => f -> s -> t Source #

app5 :: AppN f s 4 t => f -> s -> t Source #

app6 :: AppN f s 5 t => f -> s -> t Source #

app7 :: AppN f s 6 t => f -> s -> t Source #

app8 :: AppN f s 7 t => f -> s -> t Source #

app9 :: AppN f s 8 t => f -> s -> t Source #

app10 :: AppN f s 9 t => f -> s -> t Source #

Constructing tuples

consT :: ConsT a s t => a -> s -> t Source #

Adds an element to the head of an n-ary tuple

>>> consT 5 (True,'c')
(5,True,'c')

snocT :: SnocT a s t => a -> s -> t Source #

Adds an element to the back of an n-ary tuple

>>> snocT 5 (True,'c')
(True,'c',5)

appendT :: AppendT s r t => s -> r -> t Source #

Appends two n-ary tuple into one larger tuple

>>> appendT (5,'c') ('d',False)
(5,'c','d',False)

reverseT :: ReverseT s t => s -> t Source #

Reverses the order of elements in an n-ary tuple

>>> reverseT (1,2,3,4)
(4,3,2,1)

initT :: InitT s t => s -> t Source #

Takes an n-ary tuple and returns the same tuple minus the first element.

>>> initT (1,2,3,4)
(1,2,3)

Works only only tuples of size at least 3

>>> initT (1,2)
Couldn't match type `2 ':<= 3' with `2 ':>= 3'

tailT :: TailT s t => s -> t Source #

Takes an n-ary tuple and returns the same tuple minus the first element.

>>> tailT (1,2,3,4)
(2,3,4)

Works only only tuples of size at least 3

>>> tailT (1,2)
Couldn't match type `2 ':<= 3' with `2 ':>= 3'

Insertion

ins :: Insert a s t => a -> s -> t Source #

Inserts an element into an n-ary tuple. Its position is determined by the target type

>>> ins 5 ('c', False) :: (Char, Integer, Bool)
('c',5,False)

An element will only be inserted at a specific position if:

  • The element type matches the component type
  • The tail of the tuple remains well-typed
>>> ins 5 ('c',1,False) :: (Char, Integer, Bool, Integer)
('c',1,False,5)

In the above example, inserting 5 after c would make the tail of the tuple have type (Integer, Bool) when the target type asks for (Bool,Integer)

When attempting to insert an element before or after a component of the same type the element is always inserted in front

>>> ins 5 ('c',1,False) :: (Char, Integer, Integer, Bool)
('c',5,1,False)

insN :: InsertN a s n t => a -> s -> Proxy n -> t Source #

Inserts an element at an index specified position into an n-ary tuple

>>> insN 5 ('c',1,False) (Proxy :: Proxy 1)
('c',5,1,False)

ins1 :: InsertN a s 0 t => a -> s -> t Source #

Inserts an element in head position into an n-ary tuple

>>> ins1 5 ('c',1,False)
(5,'c',1,False)

ins2 :: InsertN a s 1 t => a -> s -> t Source #

ins3 :: InsertN a s 2 t => a -> s -> t Source #

ins4 :: InsertN a s 3 t => a -> s -> t Source #

ins5 :: InsertN a s 4 t => a -> s -> t Source #

ins6 :: InsertN a s 5 t => a -> s -> t Source #

ins7 :: InsertN a s 6 t => a -> s -> t Source #

ins8 :: InsertN a s 7 t => a -> s -> t Source #

ins9 :: InsertN a s 8 t => a -> s -> t Source #

ins10 :: InsertN a s 9 t => a -> s -> t Source #

Deletion

del :: Delete s t => s -> t Source #

Deletes the first element in an n-ary tuple whose type does not exist in the target type

>>> del ('c',False,5) :: (Char,Bool)
('c',False)

delN :: DeleteN s n t => s -> Proxy n -> t Source #

Deletes an element specified by an index in an n-ary tuple

>>> delN ('c',False,5) (Proxy :: Proxy 1)
('c',5)

convenience functions

del1 :: DeleteN s 0 t => s -> t Source #

Deletes the first element of an n-ary tuple

>>> del1 ('c',False,5)
(False,5)

del2 :: DeleteN s 1 t => s -> t Source #

del3 :: DeleteN s 2 t => s -> t Source #

del4 :: DeleteN s 3 t => s -> t Source #

del5 :: DeleteN s 4 t => s -> t Source #

del6 :: DeleteN s 5 t => s -> t Source #

del7 :: DeleteN s 6 t => s -> t Source #

del8 :: DeleteN s 7 t => s -> t Source #

del9 :: DeleteN s 8 t => s -> t Source #

del10 :: DeleteN s 9 t => s -> t Source #

Folding

foldlT :: FoldLeft f s t => f -> t -> s -> t Source #

Fold left for n-ary tuples

>>> foldlT (-) 0 (4,3,2,1)
-10

foldrT :: FoldRight f s t => f -> t -> s -> t Source #

Fold right for n-ary tuples

>>> foldrT (-) 0 (4,3,2,1)
2

Currying

uncurryT :: UnCurryT s t b => s -> t -> b Source #

Converts a curried function to a function that works on n-ary tuples

>>> uncurryT (\a b c -> a + b + c) (1,2,3)
6

curryT :: CurryT s t => s -> t Source #

Converts a function that works on n-ary tuples to a curried function

>>> curryT (\(a,b,c) -> a + b + c) 1 2 3 :: Integer
6

Currently, type inference is partially broken for this function