Каков общий случай функции продвижения 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
,