Обобщение сильных и замкнутых профункторов - PullRequest
9 голосов
/ 13 марта 2019

Я смотрел на классы сильных и закрытых профессоров:

class Profunctor p where
    dimap :: (a' -> a) -> (b -> b') -> p a b -> p a' b'
class Profunctor p => Strong p where
    strong :: p a b -> p (c, a) (c, b)
class Profunctor p => Closed p where
    closed :: p a b -> p (c -> a) (c -> b)

((,) - симметричный бифунктор, поэтому он эквивалентен определению в пакете "profunctors".)

Замечу, что и (->) a, и (,) a являются эндофункторами. Кажется, Strong и Closed имеют похожую форму:

class (Functor f, Profunctor p) => C f p where
    c :: p a b -> p (f a) (f b)

Действительно, если мы посмотрим на законы, некоторые из них также имеют подобную форму:

strong . strong ≡ dimap unassoc assoc . strong
closed . closed ≡ dimap uncurry curry . closed

lmap (first f) . strong ≡ rmap (first f) . strong
lmap (. f)     . closed ≡ rmap (. f)     . closed

Являются ли они обоими частными случаями некоторого общего случая?

Ответы [ 2 ]

4 голосов
/ 13 марта 2019

Вы можете добавить Choice в список.И Strong, и Choice (или декартовы и кокартезианские, как их называет Джереми Гиббонс) являются примерами модулей Tambara.Я говорю об общей схеме, включающей Closed в своем блоге на profunctor optics (перейдите к разделу Обсуждение) под именем Related.

0 голосов
/ 13 марта 2019

Очень интригующе.Это не совсем ответ, просто мысли ...

Так что нам нужна абстракция над (,) и (->), которая предлагает обобщение assoc / curry и first /precompose.Я обращусь к первым:

class Isotropic f where
  lefty :: f a (f b c) -> f (a,b) c
  righty :: f (a,b) c -> f a (f b c)
  -- lefty ≡ righty⁻¹

instance Isotropic (,) where
  lefty (a,(b,c)) = ((a,b),c)
  righty ((a,b),c) = (a,(b,c))

instance Isotropic (->) where
  lefty = uncurry
  righty = curry

Легко.Вопрос в том, есть ли другие примеры этого?Конечно, есть тривиальный

newtype Biconst c a b = Biconst c

instance Isotropic (Biconst c) where
  lefty (Biconst c) = Biconst c
  righty (Biconst c) = Biconst c

Тогда получившийся в результате обличитель

class Profunctor p => Stubborn p where
  stubborn :: p a b -> p (Biconst d c a) (Biconst d c b)

можно было бы также написать

class Profunctor p => Stubborn p where
  stubborn :: p a b -> p d d

Но примеры этого, кажется, выходятскорее, слишком тривиально, чтобы быть пригодным для использования:

instance Stubborn (->) where
  stubborn _ = id
instance (Monad m) => Stubborn (Kleisli m) where
  stubborn (Kleisli _) = Kleisli pure
instance (Monoid m) => Stubborn (Forget m) where
  stubborn (Forget _) = Forget $ const mempty

Я подозреваю, что (,) и (->) действительно являются единственными полезными случаями для этого, потому что они являются «свободным бифунктором» / «свободным»профюнктор »соответственно.

...