In a pure functional language, the only thing you can do with a value is apply a function to it.
In other words, if you want to do anything interesting with a value of t
This question is a window into a number of deeper concepts.
First, note there is an ambiguity in this question. Do we mean the type forall b. (a -> b) -> b
, such that we can instantiate b
with whatever type we like, or do we mean (a -> b) -> b
for some specific b
that we cannot choose.
We can formalize this distinction in Haskell thus:
newtype Cont b a = Cont ((a -> b) -> b)
newtype Cod a = Cod (forall b. (a -> b) -> b)
Here we see some vocabulary. The first type is the Cont monad, the second is CodensityIdentity, though my familiarity with the latter term isn't strong enough to say what you should call that in English.
Cont b a
can't be equivalent to a
unless a -> b
can hold at least as much information as a
(see Dan Robertson's comment below). So, for example, notice that you can never get anything out of Cont
Voida
.
Cod a
is equivalent to a
. To see this it is enough to witness the isomorphism:
toCod :: a -> Cod a
fromCod :: Cod a -> a
whose implementations I'll leave as an exercise. If you want to really do it up, you can try to prove that this pair really is an isomorphism. fromCod . toCod = id
is easy, but toCod . fromCod = id
requires the free theorem for Cod
.