Итак, насколько я могу судить, идея этих диаграмм заключается в том, что вам даны:
- типы
A
, B
и Z
- функция
f
и g
указанных типов (на первой диаграмме f :: Z -> A
и g :: Z -> B
, на второй стрелки идут «в другую сторону», поэтому f :: A -> Z
и g :: B -> Z
).
Сейчас я сконцентрируюсь на первой диаграмме, чтобы мне не приходилось говорить все дважды с небольшими вариациями.
В любом случае, учитывая вышеизложенное, идея заключается в том, что существуеттип M
вместе с функциями fst :: M -> A
, snd :: M -> B
и h :: Z -> M
, так что, как говорят математики, диаграмма "коммутирует".Под этим просто подразумевается, что с учетом любых двух точек на диаграмме, если вы будете следовать стрелкам каким-либо образом от одной к другой, результирующие функции будут одинаковыми.То есть f
- это то же самое, что и fst . h
, а g
- это то же самое, что и snd . h
Легко видеть, что независимо от того, что Z
, тип пары (A, B)
вместе с обычными функциями Haskell fst
и snd
удовлетворяет это - вместе с соответствующим выбором h
, а именно:
h z = (f z, g z)
, который тривиально удовлетворяет двум требуемым тождествам длядиаграмма для коммутирования.
Это базовое объяснение диаграммы.Но вы можете быть немного озадачены ролью Z
во всем этом.Это возникает потому, что то, что на самом деле говорится, довольно сильно.Это то, что, учитывая A
, B
, f
и g
, существует M
вместе с функциями fst
и snd
, что вы можете построить такую диаграмму для любого type Z
(что также означает предоставление функции h :: Z -> M
).И далее, что есть только одна функция h
, которая удовлетворяет требуемым свойствам.
Довольно ясно, как только вы поиграете с ней и поймете различные требования, эта пара (A, B)
и различные другие типы, изоморфные ему (что в основном означает MyPair A B
, где вы определили data MyPair a b = MyPair a b
), являются единственными вещами, которые удовлетворяют этому.И что есть другие типы M
, которые также будут работать, но которые дадут различные различные h
s - например.принять M
как тройное (A, B, Int)
, с fst
и snd
извлечением ("проецированием" в математической терминологии) первого и второго компонентов, а затем h z = (f z, g z, x)
является такой функцией для любого x :: Int
что вы хотите назвать.
Прошло слишком много времени с тех пор, как я изучал математику и, в частности, теорию категорий, чтобы доказать, что пара (A, B)
является единственным типом, который удовлетворяет "универсальному свойству", которое мыВы говорите - но будьте уверены, что это так, и вам действительно не нужно это понимать (или вообще что-либо из этого), чтобы иметь возможность программировать с типами товаров и сумм в Haskell.
Вторая диаграмма более или менее такая же, но со всеми перевернутыми стрелками.В этом случае «копроцесс» или «сумма» M
из A
и B
оказывается Either a b
(или чем-то изоморфным для него), и h :: M -> Z
будет определяться как:
h (Left a) = f a
h (Right b) = g b