强封闭发音器的泛化
Generalization of strong and closed 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
都是内函子。似乎 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
这些都是一般情况的特例吗?
非常有趣。这不是真正的答案,只是想法...
所以我们需要的是对 (,)
和 (->)
的抽象,它提供 assoc
/curry
和 first
/[=20= 的概括].我将解决前者:
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
我怀疑 (,)
和 (->)
真的是唯一有用的情况,因为它们分别是“自由双函数”/“自由profunctor”。
您可以将 Choice
添加到列表中。 Strong
和 Choice
(或笛卡尔坐标和柯笛坐标,Jeremy Gibbons 称它们为)都是 Tambara 模块的示例。我在 profunctor optics 上的博客 post 中讨论了包含 Closed
的一般模式(跳至讨论部分),名称为 Related
.
我在看 类 强大而封闭的发音者:
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
这些都是一般情况的特例吗?
非常有趣。这不是真正的答案,只是想法...
所以我们需要的是对 (,)
和 (->)
的抽象,它提供 assoc
/curry
和 first
/[=20= 的概括].我将解决前者:
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
我怀疑 (,)
和 (->)
真的是唯一有用的情况,因为它们分别是“自由双函数”/“自由profunctor”。
您可以将 Choice
添加到列表中。 Strong
和 Choice
(或笛卡尔坐标和柯笛坐标,Jeremy Gibbons 称它们为)都是 Tambara 模块的示例。我在 profunctor optics 上的博客 post 中讨论了包含 Closed
的一般模式(跳至讨论部分),名称为 Related
.