О вложенных типах подвески CPS

Начнем со знакомого типа приостановленных вычислений CPS, (a -> r) -> r, который пишется как Cont r a на языке mtl. Мы знаем, что он изоморфен a, пока он остается полиморфным в r. Если мы вложим этот тип, мы получим этот тип ранга 3:

forall r. ((forall s. (a -> s) -> s) -> r) -> r

(Ради удобства я мог бы дать определение type Susp a = forall r. (a -> r) -> r, а затем начать говорить о Susp (Susp a), но боюсь, что это отвлечет внимание на технические детали.)

Мы можем получить аналогичный тип, универсально определяя тип результата только после вложения, как это было бы, если бы у нас было forall r. Cont r (Cont r a):

forall r. (((a -> r) -> r) -> r) -> r

Есть ли какая-то существенная разница между этими двумя типами? Я говорю осмысленно, потому что некоторые вещи, которые, по-видимому, можно сделать только с первым типом SuspSusp...

GHCi> foo = (\kk -> kk (\k -> k True)) :: forall s. ((forall r. (Bool -> r) -> r) -> s) -> s
GHCi> bar = (\kk -> kk (\k -> k True)) :: forall r. (((Bool -> r) -> r) -> r) -> r
GHCi> foo (\m -> show (m not))
"False"
GHCi> bar (\m -> show (m not))

<interactive>:76:12: error:
    * Couldn't match type `[Char]' with `Bool'
      Expected type: Bool
        Actual type: String
    * In the expression: show (m not)
      In the first argument of `bar', namely `(\ m -> show (m not))'
      In the expression: bar (\ m -> show (m not))

... также может быть достигнуто со вторым, «ContCont», используя бесплатную теорему для (a -> r) -> r, f (m g) = m (f . g) для любого m :: (a -> r) -> r.

GHCi> foo (\m -> m (show . not))
"False"
GHCi> bar (\m -> m (show . not))
"False"

person duplode    schedule 26.04.2018    source источник
comment
Поскольку Susp a изоморфен a, отсюда следует, что Susp (Susp a) также изоморфен a. Таким образом, ваш вопрос сводится к тому, изоморфен ли forall r. Cont r (Cont r a) a.   -  person Twan van Laarhoven    schedule 26.04.2018
comment
Я не понимаю вашего утверждения о свободной теореме. Можете ли вы уточнить, какие переменные должны быть определены количественно?   -  person dfeuer    schedule 26.04.2018
comment
@TwanvanLaarhoven Да, это другой взгляд на это. (Изначально меня интересовало соотношение Cont r (Cont r a) и Susp a; затем я переключился на формулировку в этом посте, надеясь, что она внесет дополнительную ясность.)   -  person duplode    schedule 26.04.2018
comment
@dfeuer r определяется количественно; с g :: a -> r и f :: r -> s. (Возможно, для ясности мне следовало написать (A -> r) -> r.)   -  person duplode    schedule 26.04.2018


Ответы (2)


(частичный ответ)

Я не удивлюсь, если a окажется изоморфным предложенному вами типу.

forall r. (((a -> r) -> r) -> r) -> r

До сих пор мне удалось только доказать, что первое встраивается во второе. Вложение также может быть изоморфизмом, но если это так, чтобы доказать, что нам, вероятно, потребуется использовать параметричность на страшном типе выше.

Вот вложение:

type YD a = forall r. (((a -> r) -> r) -> r) -> r

ydosi :: a -> YD a
ydosi x = \f -> f (\g -> g x)

ydiso :: YD a -> a
ydiso x = x (\a -> a id)

Доказать, что это вложение, легко, и для этого требуются только бета-шаги:

ydiso (ydosi x)
= ydiso (\f -> f (\g -> g x))
= (\f -> f (\g -> g x)) (\a -> a id)
= (\a -> a id) (\g -> g x)
= (\g -> g x) id
= id x
= x

Противоположное направление намного сложнее, и (если возможно) следует полагаться на параметричность x :: YD a. Завершение этого докажет желаемый изоморфизм.

ydosi (ydiso x)
= ydosi (x (\a -> a id))
= \f -> f (\g -> g (x (\a -> a id)))
= ????
= x
person chi    schedule 26.04.2018
comment
Да, более сложное направление кажется таким близким, но все же таким далеким... Интересно, показать ли, что ydiso инъективно, или что ydosi сюръективно (чего, я думаю, должно быть достаточно, чтобы получить другое направление, учитывая то, которое у нас уже есть). ), хотя он, вероятно, требует параметризации аналогичным образом. - person duplode; 27.04.2018
comment
Спустя некоторое время я стал достаточно уверенным в своей попытке выбраться из этой привязки, чтобы опубликовать ее как дополнительный ответ . Я хотел бы услышать ваше мнение об этом. - person duplode; 16.06.2018

Я не совсем уверен в следующем взгляде на этот вопрос (это слишком хорошо, чтобы быть правдой), но это лучшее, что я могу предложить на данный момент, так что давайте выложим его на стол.

ответ Чи решает проблему, предлагая кандидата на изоморфизм между a и forall r. (((a -> r) -> r) -> r) -> r:

-- If you want to play with these in actual code, make YD a newtype.
type YD a = forall r. (((a -> r) -> r) -> r) -> r

ydosi :: a -> YD a
ydosi x = \kk -> kk (\k -> k x)

ydiso :: YD a -> a
ydiso mm = mm (\m -> m id)

Затем чи доказывает ydiso . ydosi = id, что оставляет направление ydosi . ydiso для рассмотрения.

Теперь, если у нас есть некоторое f и его левое обратное g (g . f = id), из этого легко следует, что f . g . f = f. Если f сюръективно, мы можем «отменить» его справа, что приведет нас к f . g = id (то есть к другому направлению изоморфизма). Если это так, то, учитывая, что у нас есть ydiso . ydosi = id, достаточно установить, что ydosi сюръективно, чтобы доказать изоморфизм. Один из способов разобраться в этом — порассуждать о жителях YD a.

(Хотя я не буду пытаться делать это здесь, я предполагаю, что следующие отрывки можно уточнить, выразив их в терминах правил ввода System F -- см. этот вопрос Math.SE.)

Значение YD A — это функция, которая принимает продолжение:

mm :: forall r. (((A -> r) -> r) -> r) -> r
mm = \kk -> _y
-- kk :: forall r. ((A -> r) -> r) -> r
-- _y :: r

Единственный способ получить здесь результат типа r — применить kk к чему-то:

mm :: forall r. (((A -> r) -> r) -> r) -> r
mm = \kk -> kk _m
-- kk :: forall r. ((A -> r) -> r) -> r
-- _m :: forall r. (A -> r) -> r

Поскольку тип kk полиморфен в r, таким же должен быть и тип _m. Это означает, что мы также знаем, каким должно быть _m, благодаря знакомому изоморфизму A/forall r. (A -> r) -> r:

mm :: forall r. (((A -> r) -> r) -> r) -> r
mm = \kk -> kk (\k -> k _x)
-- kk :: forall r. ((A -> r) -> r) -> r
-- k :: forall r. (A -> r) -> r
-- _x :: A

Однако правая часть выше — это именно ydosi:

mm :: forall r. (((A -> r) -> r) -> r) -> r
mm = ydosi _x
-- _x :: A

Мы только что выяснили, что любое значение forall r. (((A -> r) -> r) -> r) -> r равно ydosi x для некоторого x :: A. Отсюда немедленно следует, что ydosi сюръективно, чего достаточно для доказательства изоморфизма.

Поскольку a изоморфен forall r. ((forall s. (a -> s) -> s) -> r) -> r (см. комментарий Твана ван Лаарховена) и forall r. (((a -> r) -> r) -> r) -> r, транзитивность означает, что оба вложенных типа подвески изоморфны.


Как выглядят свидетели изоморфизма вложенной подвески? Если мы определим...

-- The familiar isomorphism.
type Susp a = forall r. (a -> r) -> r

suosi :: a -> Susp a
suosi x = \k -> k x

suiso :: Susp a -> a
suiso m = m id

...мы можем написать...

ydosi . suiso . suiso :: Susp (Susp a) -> YD a
suosi . suosi . ydiso :: YD a -> Susp (Susp a)

... что сводится к:

-- A few type annotations would be necessary to persuade GHC about the types here.
\mm -> \kk -> kk (\k -> k (mm id id)) -- Susp (Susp a) -> YD a
\mm -> \kk -> kk (\k -> k (mm (\m -> m id))) -- YD a -> Susp (Susp a)

Мы можем применить Susp a теорему о свободе к mm в первом свидетеле...

f (mm g) = mm (f . g) -- Free theorem
f (mm id) = mm f

mm id id
($ id) (mm id)
mm ($ id)
mm (\m -> m id)

... и так:

\mm -> \kk -> kk (\k -> k (mm (\m -> m id))) -- Susp (Susp a) -> YD a
\mm -> \kk -> kk (\k -> k (mm (\m -> m id))) -- YD a -> Susp (Susp a)

Удивительно, но свидетели «те же самые», за исключением их типов. Интересно, есть ли какие-то аргументы, исходящие из этого наблюдения, которые позволили бы нам двигаться назад и доказать изоморфизм более прямым способом.

person duplode    schedule 16.06.2018