Ответ 1
Да, на самом деле любой функтор приводит к созданию уникальной comonad таким образом, если f == 0.
Пусть F - контур на Hask. Пусть
W(a) = ∀r.F(a->r)->r
W(f) = F(f∗)∗
where g∗(h) = h∘g
Головоломка становится геометрической/комбинаторной по своей природе, как только вы осознаете следующий изоморфизм:
Теорема 1.Предположим, что ни один из типов (∀r.r- > F (r)) (∀r.F(r) → r) пуст. Тогда существует изоморфизм типов W (a) ≃ (∀r.F(r) → r, a).
Доказательство:class Functor f => Fibration f where
projection :: ∀r. f(r)->r
some_section :: ∀r. r->f(r) -- _any_ section will work
to :: forall f a. Fibration f
=> (∀r.f(a->r) -> r)
-> (∀r.f(r)->r, a)
to(f) = ( f . fmap const
, f(some_section(id)))
from :: forall f a. Fibration f
=> (∀r.f(r)->r, a)
-> (∀r.f(a->r) -> r)
from (π,η) = ev(η) . π
ev :: a -> (a->b) -> b
ev x f = f x
Заполнение сведений об этом (которое я могу отправить по запросу) потребует немного параметричности и леммы Йонеды. Когда F не является расслоением (как я определил выше), W тривиально, как вы заметили.
Назовем расслоение накрытием, если проекция является уникальной (хотя я не уверен, что это использование подходит).
Применяя теорему, вы можете видеть W (a) как копроизведение индексированного всеми возможными расслоениями ∀r.F(r) → r, т.е.
W(a) ≃ ∐a
π::∀f.F(r)->r
Другими словами, функтор W (как предпучок на Func (Hask)) принимает расслоение и строит из него канонически тривиализованное накрывающее пространство.
В качестве примера, пусть F (a) = (Int, a, a, a). Тогда мы имеем три очевидных естественных расслоения F (a) → a. Написав копроизведение на +, следующая диаграмма вместе с вышеприведенной теоремой, должно быть, достаточно, чтобы описать comonads конкретно:
a
^
| ε
|
a+a+a
^ | ^
Wε | |δ | εW
| v |
(a+a+a)+(a+a+a)+(a+a+a)
Таким образом, конгрессия уникальна. Используя очевидные индексы в копроизведение, Wε отображает (i, j) в j, εW отображает (i, j) в i. Таким образом, δ должно быть единственным "диагональным" отображением, а именно δ (i) == (i, i)!
Теорема 2.Пусть F - расслоение и ΩW - множество всех комонад с основополагающим функтором W. Тогда ΩW≃1.
(Извините, я не формализовал доказательство.)
Интересен и аналогичный комбинаторный аргумент для множества монад MW, но в этом случае МW может быть не одиночным. (Возьмем некоторую константу c и положим η: 1- > c и μ (i, j) = я + j-c.)
Заметим, что построенные монады/комонады не являются дуальными для исходных комонад/монад вообще. Например, пусть M - монада
(F (a) = (Int, a), η (x) = (0, x), μ (n, (m, x)) = (n + m, x)), т.е. a Writer
. Естественная проекция единственна, следовательно, по теореме W (a) ≃a, и нет возможности уважать исходную алгебру.
Обратите внимание также, что comonad тривиально является Fibration (возможно, многими разными способами), если Void
, поэтому вы получили Monad из Comonad (но это не обязательно уникально!).
Несколько комментариев о ваших наблюдениях:
-
Dual IO a
по существу VoidНасколько я знаю, в Haskell IO определено что-то вроде:
-- ghc/libraries/ghc-prim/GHC/Types.hs newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
что означает только из теории типов, соответствующее покрытие является единственным каноническим накрывающим пространством, индексированным всеми
State# RealWorld
s. Можете ли вы (или должны) отвергнуть это, вероятно, философский, а не технический вопрос. -
MonadPlus m => Dual m a
- VoidПравильно, но заметим, что если F (a) = 0, то W (a) = 1, и это не комонада (так как в противном случае у канита будет подразумеваться тип W (0) → 0 ≃ 1- > 0), Это единственный случай, когда W даже не может быть тривиальной комонадой, заданной произвольным функтором.
-
Dual Reader
есть.. Иногда эти утверждения могут быть правильными, иногда нет. Зависит от того, согласуется ли (со) алгебра с алгеброй (bi) покрытий.
Итак, я удивлен, насколько интересным является геометрический Haskell! Я думаю, что может быть очень много геометрических конструкций, подобных этому. Например, естественным обобщением этого было бы рассмотреть "каноническую тривиализацию" F- > G для некоторых ковариантных функторов F, G. Тогда группа автоморфизмов для базового пространства уже не будет тривиальной, поэтому для правильного понимания этого потребуется немного больше теории.
Наконец, здесь доказательство кода концепции. Спасибо за отличную освежающую головоломку и очень веселое Рождество; -)
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Comonad
class Functor f => Fibration f where
x0 :: f ()
x0 = some_section ()
some_section :: forall r. r -> f(r)
some_section x = fmap (const x) x0
projection :: forall r. f(r) -> r
newtype W f a = W { un_w :: forall r. f(a->r)->r }
instance Functor f => Functor (W f) where
fmap f (W c) = W $ c . fmap (. f)
instance Fibration f => Comonad (W f) where
extract = ε
duplicate = δ
-- The counit is determined uniquely, independently of the choice of a particular section.
ε :: forall f a. Fibration f => W f a -> a
ε (W f) = f (some_section id)
-- The comultiplication is unique too.
δ :: forall f a. Fibration f => W f a -> W f (W f a)
δ f = W $ ev(f) . un_w f . fmap const
ev :: forall a b. a -> (a->b)->b
ev x f = f x
-- An Example
data Pair a = P {p1 ::a
,p2 :: a
}
deriving (Eq,Show)
instance Functor Pair where
fmap f (P x y) = P (f x) (f y)
instance Fibration Pair where
x0 = P () ()
projection = p1
type PairCover a = W Pair a
-- How to construct a cover (you will need unsafePerformIO if you want W IO.)
cover :: a -> W Pair a
cover x = W $ ev(x) . p1