-lambda conversion. We'll adapt the notational strategy developed in
-Barker and Shan 2014:
-
-Instead of writing
-
- \k.g(kf): (α -> ρ) -> ρ
-
-we'll write
-
- g[] ρ
- --- : ---
- f α
-
-Then
- []
- mid(x) = --
- x
-
-and
-
- g[] ρ h[] ρ g[h[]] ρ
- --- : ---- ¢ --- : --- = ------ : ---
- f α->β x α fx β
-
-Here's the justification:
-
- (\FXk.F(\f.X(\x.k(fx)))) (\k.g(kf)) (\k.h(kx))
- ~~> (\Xk.(\k.g(kf))(\f.X(\x.k(fx)))) (\k.h(kx))
- ~~> \k.(\k.g(kf))(\f.(\k.h(kx))(\x.k(fx)))
- ~~> \k.g((\f.(\k.h(kx))(\x.k(fx)))f)
- ~~> \k.g((\k.h(kx))(\x.k(fx)))
- ~~> \k.g(h(\x.k(fx))x)
- ~~> \k.g(h(k(fx)))
-
-Then
- (\ks.k(ks))[]
- shift = \k.k(k("")) = -------------
- ""
-
-Let 2 == \ks.k(ks).
-
-so aSc lifted into the monad is
-
- [] 2[] []
- -- ¢ ( --- ¢ --- ) =
- a "" c
-
-First, we need map2 instead of map1. Second, the type of the shift
-operator will be a string continuation, rather than a function from
-string continuations to string continuations.
-
-(\k.k(k1))(\s.(\k.k(k2))(\r.sr))
-(\k.k(k1))(\s.(\r.sr)((\r.sr)2))
-(\k.k(k1))(\s.(\r.sr)(s2))
-(\k.k(k1))(\s.s(s2))
-(\s.s(s2))((\s.s(s2))1)
-(\s.s(s2))(1(12))
-(1(12))((1(12)2))
-
-
-
-
-
-But here's the interesting part: from the point of view of the shift
-operator, the continuation that it will be fed will be the entire rest
-of the computation. This includes not only what has come before, but
-what will come after it as well. That means when the continuation is
-doubled (self-composed), the result duplicates not only the prefix
-`(ab ~~> abab)`, but also the suffix `(d ~~> dd)`. In some sense, then,
-continuations allow functions to see into the future!
-
-What do you expect will be the result of executing "aScSe" under the
-second perspective? The answer to this question is not determined by
-the informal specification of the task that we've been using, since
-under the new perspective, we're copying complete (bi-directional)
-contexts rather than just left contexts.
-
-It might be natural to assume that what execution does is choose an S,
-and double its context, temporarily treating all other shift operators
-as dumb letters, then choosing a remaining S to execute. If that was
-our interpreation of the task, then no string with more than one S
-would ever terminate, since the number S's after each reduction step
-would always be 2(n-1), where n is the number before reduction.
-
-But there is another equally natural way to answer the question.
-Assume the leftmost S is executed first. What will the value of its
-continuation k be? It will be a function that maps a string s to the
-result of computing `ascSe`, which will be `ascascee`. So `k(k "")`
-will be `k(acacee)`, which will result in `a(acacee)ca(acacee)cee`
-(the parentheses are added to show stages in the construction of the
-final result).
-
-So the continuation monad behaves in a way that we expect a
-continuation to behave. But where did the continuation monad come
-from? Let's consider some ways of deriving the continuation monad.