Итак, если f
и g
- правильные функторы, forall a. f a -> g a
- естественное преобразование. Мы могли бы сделать его немного красивее:
type f ~> g = forall a. f a -> g a
Подобные естественные преобразования позволяют сформировать категорию функторов Haskell, так что у вас есть функтор из этой категории в некоторую другую категорию.
Следуя шагам обычных функторов Haskell, возможно, имеет смысл сделать x
эндофунктором, отображающим функторы на другие функторы. Это похоже, но не идентично тому, что у вас есть:
class FFunctor x where
ffmap :: (f ~> g) -> (x f ~> x g)
Однако в вашем случае x f
и x g
не являются функторами, а x f -> x g
- это обычная функция, а не естественное преобразование. Тем не менее, картина достаточно близка, чтобы показаться интригующей.
Имея это в виду, кажется, что x
все еще является примером функтора, только между двумя разными категориями. Он переходит из категории Функторов в категорию x
с различными структурами. Каждый возможный x
, как и Foo
, образует категорию с такими объектами, как Foo []
и Foo Maybe
, и преобразованиями между ними (Foo [] -> Foo Maybe
). Ваша interleaveHomomorphism
функция "поднимает" естественные преобразования в эти x-morphisms
, точно так же, как fmap
"поднимает" обычные (a -> b
) функции в функции в образе функтора (f a -> f b
).
Так что да: ваш класс типов - это функтор, как и Functor
, за исключением двух разных категорий. Я не знаю конкретного имени для него, в основном потому, что я не знаю конкретного имени для таких конструкций, как x
.
В общем, я даже не уверен, что конкретное имя имеет смысл. На этом этапе мы, вероятно, хотели бы иметь хороший общий класс типов функторов, который бы находился между любыми двумя категориями. Может быть, что-то вроде:
class (Category catA, Category catB) => GFunctor f catA catB where
gfmap :: catA a b -> catB (f a) (f b)
Вероятно, это уже существует где-то в библиотеке.
К сожалению, этот конкретный подход к определению различных функторов потребует дополнительных шумов newtype, поскольку (->)
уже является категорией. На самом деле, собрать все типы должным образом будет непросто.
Так что, наверное, проще всего назвать это XFunctor
или что-то в этом роде. Кроме того, только представьте себе каламбур!
РЕДАКТИРОВАТЬ: похоже, что categories
предоставляет тип CFunctor
, подобный этому , но немного умнее:
class (Category r, Category s) => CFunctor f r s | f r -> s, f s -> r where
cmap :: r a b -> s (f a) (f b)
Однако я не уверен, что даже это достаточно общее! Я думаю, что мы могли бы также захотеть, чтобы он был более полиморфным по сравнению с видами.
person
Tikhon Jelvis
schedule
06.06.2014