Функтор предназначен для (a -> b) -> (fa -> fb), что для (Категория c) => cab -> c (fa) (fb)?

Я хотел бы иметь функцию для сопоставления чистой функции с контейнером или для последовательного выполнения аппликативных / монадических действий через него . Для чистого отображения мы имеем

fmap :: Functor f => (a -> b) -> (f a -> f b)

Для монадической последовательности имеем (из Data.Taversable)

mapM :: (Traversable f, Monad m) => (a -> m b) -> (f a -> m (f b))

Что похоже на

mapKleisli :: (Traversable f, Monad m) => Kleisli m a b -> Kleisli m (f a) (f b)
mapKleisli = Kleisli . mapM . runKleisli

Мы знаем, что и (->), и (Kleisli m) являются категориями (и стрелками). Поэтому естественно сделать обобщение:

mapCategory :: (X f, Category c) => c a b -> c (f a) (f b)

Знаете ли вы такой класс X с аналогичным методом? Может, где-то на взломе? Я пытался обмануть / hayoo, но не нашел ничего подходящего.

Обновление:

Теперь я лучше знаю, что мне нужно. И стрелки Клейсли, и (->) являются экземплярами ArrowApply, который по своей мощи не уступает Monad. Я придумал эту версию Travesable, основанную на стрелках:

{-# LANGUAGE TypeOperators #-}

import Prelude hiding (id, (.), mapM)
import Control.Arrow
import Control.Category

class Traversable f where
  traverse :: ArrowApply (~>) => f a -> (a ~> b) ~> f b

mapArrow :: (ArrowApply (~>), Traversable f) => a ~> b -> f a ~> f b
mapArrow a = arr (\x -> (traverse x, a)) >>> app

instance Traversable Maybe where
  traverse Nothing = arr (const Nothing)
  traverse (Just x) = arr (\a -> (a, x)) >>> app >>> arr Just

instance Traversable [] where
  traverse [] = arr (const [])
  traverse (x : xs) = undefined -- this is hard!

Я мог бы использовать просто обычный Traversable на основе Applicative, с Identity для чистых функций, но я не уверен, что это хорошо. Странно рассматривать чистые функции как частный случай монадических действий. Интерпретация как чистых функций, так и монадических действий как экземпляров некоторого класса действий (Category / Arrow / ArrowApply) кажется мне более простой.

Вопросы: не хотите ли вы закончить экземпляр для []? Имеет ли смысл мое мнение о ArrowApply и Monad?

15
задан Andrey Tyukin 9 July 2018 в 23:50
поделиться