Home > Net >  How to build a new tuple in Haskell by adding a element to a given tuple
How to build a new tuple in Haskell by adding a element to a given tuple

Time:06-29

How can I add an element to a tuple?

Say, I have a tuple:

info = (13, "Arrabella")

Now I want to create a new tuple conatining the given tuple plus a new element 3.17, so when starting with a the resulting tuple should be like following:

(13, "Arrabella", 3.17)

Any idea how to do this? The operator I'd use to do this with a List doesn't seem to be implemented for tuples...

CodePudding user response:

You can map the existing values to a new 3-tuple, so:

info2 = (i1, i2, 3.17) where (i1, i2) = info

The operator I'd use to do this with a List doesn't seem to be implemented for tuples...

Indeed, ( ) :: [a] -> [a] -> [a] takes two lists and returns a list that is the concatenation of the two given lists. This also means that the items in the list all have the same type, and that the items in the two lists have the same type.

One could make a typeclass to concatenate tuples with an arbitrary length, for example with:

{-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses #-}

class TupleAppend a b c | a b -> c where
    (   ) :: a -> b -> c

instance TupleAppend (a, b) (c, d) (a, b, c, d) where
    (a, b)     (c, d) = (a, b, c, d)

instance TupleAppend (a, b) (c, d, e) (a, b, c, d, e) where
    (a, b)     (c, d, e) = (a, b, c, d, e)

-- …


instance TupleAppend (a, b, c) (d, e) (a, b, c, d, e) where
    (a, b, c)     (d, e) = (a, b, c, d, e)

instance TupleAppend (a, b, c) (d, e, f) (a, b, c, d, e, f) where
    (a, b, c)     (d, e, f) = (a, b, c, d, e, f)

-- …

But this will not help here either since you here add one element to the tuple, not concatenate two tuples. You can create an extra typeclass to append a single item:

{-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses #-}

class TupleAddL a b c | a b -> c where
    (<  ) :: a -> b -> c

class TupleAddR a b c | a b -> c where
    (  >) :: a -> b -> c

instance TupleAddL a (b, c) (a, b, c) where
    a <   (b, c) = (a, b, c)

instance TupleAddR (a, b) c (a, b, c) where
    (a, b)   > c = (a, b, c)

instance TupleAddL a (b, c, d) (a, b, c, d) where
    a <   (b, c, d) = (a, b, c, d)

instance TupleAddR (a, b, c) d (a, b, c, d) where
    (a, b, c)   > d = (a, b, c, d)

-- …

Then you thus can use (13, "Arrabella") > 3.17 to create a 3-tuple.

CodePudding user response:

You need to use a pattern to deconstruct the tuple, and then construct the new tuple.

In ghci you must use let in front of the pattern:

Prelude> let (nr, str) = (13, "Arrabella")
Prelude> (nr, str, 13.7)
(13,"Arrabella",13.7)

In a source file you type it in directly, without let:

(a, b) = (13, "Arrabella")

Load your source with :l sourceName.hs, and:

*Main> (a, b, 13.7)
(13,"Arrabella",13.7)
  • Related