S.D.Mechveliani writes:
As Haskell has the standard functions fst, snd to decompose (a,b), maybe, it worths to provide also tuple31, tuple31, tuple31, ... tuple51, tuple52, tuple53, tuple54, tuple55
for the tuples of n = 3,4,5 ?
I've found some of these useful, except I named them differently:
fst3 :: (a,b,c) -> a fst3 (x,_,_) = x
snd3 :: (a,b,c) -> b snd3 (_,x,_) = x
thd3 :: (a,b,c) -> c thd3 (_,_,x) = x
.... never got around to quadruples etc. I also defined (some of these may be untested):
tripl :: a -> (a,a,a) tripl x = (x,x,x)
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d curry3 f x y z = f (x, y, z)
uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d) uncurry3 f t = f (fst3 t) (snd3 t) (thd3 t)
applyTriple :: (a -> b, a -> c, a -> d) -> a -> (b,c,d) applyTriple (f,g,h) x = (f x, g x, h x)
cross3 :: (a -> b, c -> d, e -> f) -> (a,c,e) -> (b,d,f) cross3 (f,g,h) (x,y,z) = (f x, g y, h z)
mapTriple :: (a -> b) -> (a, a, a) -> (b, b, b) mapTriple = cross3 . tripl
applyFst3 :: (a -> b) -> (a, c, d) -> (b, c, d) applyFst3 f = applyTriple (f . fst3, snd3, thd3)
applySnd3 :: (a -> b) -> (c, a, d) -> (c, b, d) applySnd3 f = applyTriple (fst3, f . snd3, thd3)
applyThd3 :: (a -> b) -> (c, d, a) -> (c, d, b) applyThd3 f = applyTriple (fst3, snd3, f . thd3)
applyArgs3 :: (a -> b) -> (c -> d) -> (e -> f) -> (b -> d -> f -> g) -> (a -> c -> e -> g) applyArgs3 af1 af2 af3 f = \x y z -> f (af1 x) (af2 y) (af3 z)
rotl :: (a -> b -> c -> d) -> (b -> c -> a -> d) rotl f y z x = f x y z
rotr :: (a -> b -> c -> d) -> (c -> a -> b -> d) rotr f z x y = f x y z
rotl4 :: (a -> b -> c -> d -> e) -> (b -> c -> d -> a -> e) rotl4 f y z t x = f x y z t
rotr4 :: (a -> b -> c -> d -> e) -> (d -> a -> b -> c -> e) rotr4 f t x y z = f x y z t
Some more combinators (only for pairs so far):
twin :: a -> (a,a) twin x = (x,x)
swap :: (a,b) -> (b,a) swap (x,y) = (y,x)
-- apply a pair of functions to one argument
applyPair :: (a -> b, a -> c) -> a -> (b, c) applyPair (f, g) x = (f x, g x)
-- apply a pair of functions to a pair
cross :: (a -> b, c -> d) -> (a, c) -> (b, d) cross (f, g) = applyPair (f . fst, g . snd)
-- compose a pair of functions onto one function
dotPair :: (a -> b, a -> c) -> (d -> a) -> (d -> b, d -> c) dotPair (f, g) h = (f . h, g . h)
-- compose a pair of functions onto a pair of functions
dotCross :: (a -> b, c -> d) -> (e -> a, f -> c) -> (e -> b, f -> d) dotCross (f, g) (h, i) = (f . h, g . i)
mapPair :: (a -> b) -> (a, a) -> (b, b) mapPair = cross . twin
applyFst :: (a -> b) -> (a, c) -> (b, c) applyFst f = applyPair (f . fst, snd)
applySnd :: (a -> b) -> (c, a) -> (c, b) applySnd f = applyPair (fst, f . snd)
applyArgs :: (a -> b) -> (c -> d) -> (b -> d -> e) -> (a -> c -> e) applyArgs af1 af2 f = \x y -> f (af1 x) (af2 y)
betweenFst :: (a -> b -> c) -> (a, d) -> (b, e) -> c betweenFst = applyArgs fst fst
betweenSnd :: (a -> b -> c) -> (d, a) -> (e, b) -> c betweenSnd = applyArgs snd snd
I find these combinators useful, and probably other people have their own versions - it would be nice to get them standardised, so we all speak the same language. By standardised, I mean a prominent version that will be adopted by users, not necessarily a committee process. Tim
<trb@eastpac.com.au> writes:
S.D.Mechveliani writes:
As Haskell has the standard functions fst, snd to decompose (a,b), maybe, it worths to provide also [...]
I've found some of these useful, except I named them differently:
fst3 :: (a,b,c) -> a snd3 :: (a,b,c) -> b thd3 :: (a,b,c) -> c
.... never got around to quadruples etc.
I'd like a general 'nth', but of course that would restrict us to monotyped tuples (e.g., nth :: Int -> (a,a,...,a,a) -> a ) This isn't possible to do more generally with some language extension, is it? A better way might be to define classes: class TwoTuple t a b | t -> a b where fst :: t -> a snd :: t -> b instance TwoTuple (a,b) where ... class (TwoTuple t) => ThreeTuple t c | t -> c where thd :: t -> c instance TwoTuple (a,b,c) where ... instance ThreeTuple (a,b,c) where ... --and so on. Quite verbose, but avoids the need to tag the functions with the tuple size. -kzm -- If I haven't seen further, it is by standing in the footprints of giants
Hi!
[...]
twin :: a -> (a,a) twin x = (x,x)
By using the Monad instance of ((->) a), defined in Control.Monad.Reader, one can write join (,) for twin. (And, by the way, one can use join for functions in several other useful ways. For example, one can write join (*) for a squaring function. Here one can see how practical it is to implement rather abstract concepts like monads via classes and define appropriate instances of the respective classes.)
applyFst :: (a -> b) -> (a, c) -> (b, c) applyFst f = applyPair (f . fst, snd)
applySnd :: (a -> b) -> (c, a) -> (c, b) applySnd f = applyPair (fst, f . snd)
These two can be written as first and second by using the Arrow instance of (->). I suppose that other functions you defined can be easily defined/replaced by arrow expressions as well.
[...]
Wolfgang
participants (3)
-
ketil@ii.uib.no -
trb@eastpac.com.au -
Wolfgang Jeltsch