Consider the type of a function from a
's to pairs of b
's and c
's, a -> (b, c)
. (I'll use Haskell notation for types and functions, but this isn't a question about Haskell per se.) There are many such functions, including those where both, one, or none of the (b, c)
outputs depends on a
.
Suppose, in particular, that the first output depends on a
, but the second doesn't (for example as in \a -> (a, ())
). Is it possible to write a type in polymorphic lambda calculus or Hindley-Milner characterizing all and only such functions -- in other words, the subspace of a -> (b, c)
which is isomorphic to (a -> b, c)
? In other words, can we define an f :: d
(for some type d
) such that f (\a -> (a, ()))
, f (\a -> (a, 1))
, ..., are all well typed, but f (\a -> (a, a))
, f (\a -> (a, snd a))
, ..., all aren't?
Alternatively, is there any way of statically ensuring that an element of a -> (b, c)
has this property?
a -> (b, c)
, and there is no way around that, given that I have programs that depend on the state alongside programs that don't, I need them to interact with each other in a single interface, and I need (or would very much like) to be able to statically tell when a program's value depends non-trivially on the current state. – Brunhildalift :: (a -> b, c) -> a -> (b, c)
, then have clients calllift
when they want to use one of these values that depends only trivially on the current state. – Lachrymosem = (\a -> (1, a), 1)
, suppose welift m
and sequence the result with\_ b -> (snd b, fst b)
. Then the resulting program has typea -> (a, Int)
, but theInt
value doesn't depend ona
. But we can't go back to(a -> a, Int)
, so we can't tell that our result is the same in the relevant respects asm
. This is the sort of thing that happens often in state-ful programs -- a dependency on a state is discharged by a concrete value. – Brunhilda(a -> b, c)
world until the very last moment. – Lachrymosef
in question accepted argumentsx
which in turn could, in principle, accept()
as an input. But I don't wish to monomorphizex
, i.e., restrict it to only accepting()
as an input. Is it possible to characterizef
such thatf x
is well typed iffx ()
is well typed -- without in fact applyingx
to()
(which in Haskell and HM will monomorphizex
)? – Brunhildaf :: (() -> a) -> {- whatever; perhaps () again -}
wouldn't be that type. But I suspect you should open a fresh question with a bit more context about what you're trying to achieve and why. – Lachrymose