joneshf / elm-these / These

A type that may be an a, a b, or both an a and a b at once.


type These a b
    = This a
    | That b
    | These a b

This type is very closely related to Result a b.

While Result a b models exclusive-or, this type models inclusive-or.

these : (a -> c) -> (b -> c) -> (a -> b -> c) -> These a b -> c

Destroy the structure of a These a b.

The first two functions are applied to the This a and That b values, respectively. The third function is applied to the These a b value.

mapThis : (a -> c) -> These a b -> These c b

There is only one implementation of this function. It is fully described by the type signature.

Replace any as with cs

mapThat : (b -> c) -> These a b -> These a c

There is only one implementation of this function. It is fully described by the type signature.

Replace any bs with cs

mapBoth : (a -> c) -> (b -> d) -> These a b -> These c d

There is only one implementation of this function. It is fully described by the type signature.

Replace any as with cs and replace any bs with ds.

mergeWith : (c -> c -> c) -> (a -> c) -> (b -> c) -> These a b -> c

Similar to these.

The difference is that in the These a b case we apply the second and third functions and merge the results with the first function.

merge : (a -> a -> a) -> These a a -> a

A version of mergeWith that does not modify the This a or That a values.

align : List a -> List b -> List (These a b)

Similar to List.Extra.zip except the resulting list is the length of the longer list.

We can also think of this from a relational algebra perspective (or SQL if that's your thing). We view each list as a relation (table) where the primary key is its index in the list. Then List.Extra.zip can be viewed as a natural join (inner join), and align can be viewed as a full outer join.