10

我在看强和封闭的profunctors类:

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是内函子。它似乎StrongClosed具有类似的形式:

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

这些都是一般情况的特例吗?

4

2 回答 2

6

您可以添加Choice到列表中。Strong和(或笛卡尔和cocartesian Choice,正如 Jeremy Gibbons 所说)都是 Tambara 模块的示例。我讨论了包含Closed在我的博文中关于profunctor optics的一般模式(跳到讨论部分),名称为Related.

于 2019-03-13T02:06:37.610 回答
1

很耐人寻味。这不是一个真正的答案,只是想法......

所以我们需要的是一个抽象(,)(->)它提供assoc/curryfirst/的泛化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

然后得到的profunctor

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

我怀疑(,)(->)确实是唯一有用的案例,因为它们分别是“自由双函子”/“自由函子”。

于 2019-03-13T01:33:23.460 回答