pd-andy / tuple-extra / Tuple.Extra


type alias Tuple a b =
( a, b )

By type aliasing tuples into a "normal" type, we remove the (small) effort required in reading types and signatures that have tuples in. I've found this is most beneficial when a tuple is nested inside another type. Visually, the Tuple type is now no different to List, Maybe, or Result.

For example, this:

List (Maybe (String, Int))

becomes:

List (Maybe (Tuple String Int))

Paring

pairWith : b -> a -> Tuple a b

In certain situations, this proves more "pipe friendly" than the standard Tuple.pair. Fits nicely in your update function.

{ model | count = model.count + 1 }
  |> Tuple.pairWith Cmd.none

from : a -> Tuple a a

Occasionally you might want to create a Tuple from a single value. This does just that.

Tuple.from 1 
  == (1, 1)

Manipulating

apply : (a -> b -> c) -> Tuple a b -> c

Given a function that takes two arguments, apply that function to the two values contained in a tuple.

Tuple.apply (+) (1, 2) 
  == 3

flip : Tuple a b -> Tuple b a

Flip the two values contained in a tuple.

join : String -> Tuple String String -> String

Similar to String.join but for tuples instead of lists. Given some separator string, join together two strings in a tuple.

Tuple.join " " ("Hello", "world") 
  == "Hello world"

joinBy : (a -> String) -> (b -> String) -> String -> Tuple a b -> String

Works just like join, but first converts the values of the tuple to strings. These means the function works with any type of tuple.

Tuple.joinBy String.fromInt suitToString " of " (7, Club)
  == "Seven of Clubs"

sum : Tuple number number -> number

Similar to List.sum but for tuples instead of lists. Adds together two numbers contained in a tuple.

Tuple.sum (1, 2)
  == 3

product : Tuple number number -> number

Similar to List.sum but for tuples instead of lists. Multiplies together two numbers contained in a tuple

Tuple.product (1, 2)
  == 2

sort : Tuple comparable comparable -> Tuple comparable comparable

Similar to List.sort but for tuples instead of lists. Sort values contained in a tuple from lowest to highest

Tuple.sort (2, 1)
  == (1, 2)

sortBy : (a -> comparable) -> Tuple a a -> Tuple a a

Similar to List.sortBy but for tuples instead of lists. Sort values contained in a tuple by first converting both values to a comparable. The values are sorted lowest to highest

Tuple.sortBy String.length ("mouse", "cat")
  == ("cat", "mouse")

sortWith : (a -> a -> Basics.Order) -> Tuple a a -> Tuple a a

Similar to List.sortWith but for tuples instead of lists. Instead of converting values contained in a tuple to comparables, instead supply a function that will produce an Order directly.

Tuple.sortWith Basics.compare (2, 1)
  == Tuple.sort (2, 1)
  == (1, 2)

Mapping

map : (a -> b) -> Tuple a a -> Tuple b b

Apply a function to both values contained in a tuple. This might also be known as mapBothWith or bimap.

Tuple.map negate (-3, 10)
  == (3, -10)

Maybes

sequenceMaybe : Tuple (Maybe a) (Maybe b) -> Maybe (Tuple a b)

Occasionally you might find yourself in a situation where both values contained in a tuple are Maybes. Sometimes it makes more sense to take those values and make the tuple a Maybe instead.

Tuple.sequenceMaybe (Just 10, Nothing)
  == Nothing

Tuple.sequenceMaybe (Just 10, Just "Cat")
  == Maybe (10, "Cat")

sequenceFirstMaybe : Tuple (Maybe a) b -> Maybe (Tuple a b)

Similar to sequenceMaybe but only looks at the first value in a tuple to check for nothingness.

Tuple.sequenceFirstMaybe (Just 10, "Cat")
  == Maybe (10, "Cat")

sequenceSecondMaybe : Tuple a (Maybe b) -> Maybe (Tuple a b)

Similar to sequenceMaybe but only looks at the first value in a tuple to check for nothingness.

Tuple.sequenceSecondMaybe (10, Just "Cat")
  == Maybe (10, "Cat")