Declaratively constructing cons from lambdas

cons should couple 2 items.

cons :: a -> b -> f a b
cons a b = undefined

Next we talk about its interface. head should return the first item. tail should return second item.

head :: f a b -> a
head _ = a

tail :: f a b -> b
tail _ = b

Our fictional language is a subset of haskell which only has lambdas and primitives. It does not have sum / product constructors such as (,) or Product.

As such, we want to implement a container for values using functions.

We try to do something like this, to suspend and hold the values with a function.

\_ -> a b

But obviously this does not work, since this applies a to b, rather than just suspend them.

\f -> f a b

The above is the simplest way we have around this, using a function to hold a and b.

Naturally, everything then comes together:

cons :: a -> b -> f a b
cons a b = undefined
head :: f a b -> a
head ls = ls (\a _ -> a)

tail :: f a b -> b
tail ls = ls (\_ b -> b)