Как написать репрезентативный экземпляр, используя только Распределительные свойства?
Скажи, что у меня есть Distributive
экземпляр написан для какого-то сложного пользовательского типа, Foo
, Можно ли написать Foo
"s Representable
экземпляр, используя только свойства, доступные из его Distributive
пример? И если нет, то почему Distributive
суперкласс Representable
?
1 ответ
Цитирование документации Data.Distributive
...
Категорически каждый
Distributive
функтор на самом деле является правым сопряженным, и поэтому он должен бытьRepresentable
endofunctor и сохранить все пределы. Это причудливый способ сказать, что это изоморфно(->) x
для некоторыхx
,
... а также Data.Functor.Rep
:
Functor
f
являетсяRepresentable
еслиtabulate
а такжеindex
свидетель изоморфизма(->) x
,каждый
Distributive
Functor
на самом делеRepresentable
,каждый
Representable
Functor
из Хаск в Хаск является правым сопряженным.
Data.Functor.Rep.distributeRep
свидетели того, что мы можем получить Distributable
экземпляр из Representable
:
distributeRep :: (Representable f, Functor w) => w (f a) -> f (w a)
distributeRep wf = tabulate (\k -> fmap (`index` k) wf)
Можно ли написать
Foo
"sRepresentable
экземпляр, используя только свойства, доступные из егоDistributive
пример? И если нет, то почемуDistributive
суперклассRepresentable
?
Обратите внимание, что вывод, который мы получаем из отношения суперкласса, идет в другом направлении - иначе у нас был бы, например, экземпляр Monad
из каждого Applicative
, В этом конкретном случае, как указывает документация, "каждый Distributive
Functor
на самом деле Representable
", хотя роль Rep
типа семьи в том, как Representable
сформулирован получает на пути фактической реализации tabulateDist
а также indexDist
, В любом случае, tabulateAdjunction
а также indexAdjunction
покажи, как можно это сделать. (Право примыкает к дистрибутиву, см. Также этот ответ Бенджамина Ходжсона.)