Каков общий случай функции продвижения QuickCheck?

Каков общий термин для функтора со структурой, напоминающей QuickCheck's promote функция, т. е. функция вида:

promote :: (a -> f b) -> f (a -> b)

(это обратное flip $ fmap (flip ($)) :: f (a -> b) -> (a -> f b)). Есть ли какие-нибудь функторы с такой операцией, кроме (->) r а также Id? (Я уверен, что должно быть). Погуглив "quickcheck продвижение" только включил документацию QuickCheck, которая не дает promote в более общем контексте AFAICS; поиск SO для "quickcheck продвижение" не дает результатов.

3 ответа

Решение

До сих пор я нашел эти способы построения f с promote морфизм:

  • f = Identity
  • если f и g оба имеют promote тогда функтор пары h t = (f t, g t) также делает
  • если f и g оба имеют promote тогда композиция h t = f (g t) также делает
  • если f имеет promote свойство и г любой контрафунктор, то функтор h t = g t -> f t имеет promote имущество

Последнее свойство может быть обобщено для профункторов g, но тогда f будет просто профунктором, так что, вероятно, оно не очень полезно, если только вам не нужны профункторы.

Теперь, используя эти четыре конструкции, мы можем найти много примеров функторов f для которого promote существует:

f t = (t,t)

f t = (t, b -> t)

f t = (t -> a) -> t

f t = ((t,t) -> b) -> (t,t,t)

f t = ((t, t, c -> t, (t -> b) -> t) -> a) -> t

Также обратите внимание, что promote собственность подразумевает, что f указал.

point :: t -> f t
point x = fmap (const x) (promote id)

По сути, тот же вопрос: является ли это свойство функтора сильнее монады?

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(=<<) :: Monad m => (a -> m b) -> m a -> m b

Учитывая, что Monad является более мощным интерфейсом, чем Applicative, это говорит нам о том, что a -> f b может сделать больше вещей, чем f (a -> b), Это говорит нам о том, что функция типа (a -> f b) -> f (a -> b) не может быть инъективным Домен больше, чем кодомен, вручную. Это означает, что вы никак не можете сохранить поведение функции. Это просто не работает через общие функторы.

Конечно, вы можете охарактеризовать функторы, в которых эта операция инъективна. Identity а также (->) a безусловно, примеры. Готов поспорить, что есть и другие примеры, но сразу на меня ничего не бросается.

Data.Distributive имеет

class Functor g => Distributive g where
  distribute :: Functor f => f (g a) -> g (f a)
  -- other non-critical methods

Переименовав ваши переменные, вы получите

promote :: (c -> g a) -> g (c -> a)

Используя немного неверный синтаксис для ясности,

promote :: ((c ->) (g a)) -> g ((c ->) a)

(c ->) это Functorтак что тип promote это частный случай типа distribute, Таким образом, каждый Distributive Функтор поддерживает ваш promote, Я не знаю, есть ли поддержка promote но нет Distributive,

Другие вопросы по тегам