我需要以下类功能:
class InterleavedHomomorphic x where
interleaveHomomorphism :: (forall a . f a -> g a) -> x f -> x g
显然,我为它发明的名称绝不是任何东西的官方术语,上面的类型不是很优雅。这是一个在某些库中有名称甚至实现的概念吗?有没有更合理的方法呢?
这个函数的目的是我有一些注释某些数据的上下文f
(Foo
和Bar
只是为了这个问题而随机的示例数据结构):
data Foo f = One (f (Bar f)) | Product (f (Foo f)) (f (Foo f))
data Bar f = Zero | Succ (f (Bar f))
我想以多态方式转换数据的上下文;只知道上下文之间的同态,而不是(必然)关心数据本身。这可以通过在上面的示例中提供instance InterleavedHomomorphic Foo
和instance InterleavedHomomorphic Bar
来完成。
答案 0 :(得分:17)
因此,假设f
和g
是正确的仿函数,forall a. f a -> g a
是一种自然转换。我们可以让它更漂亮一点:
type f ~> g = forall a. f a -> g a
像这样的自然变换让我们形成了一个Haskell Functors的类别,所以你拥有的是一个从那个到另一个类别的仿函数。
按照普通Haskell Functors的步骤,将x
作为endofunctor,将Functors映射到其他Functors可能是有意义的。这与您所拥有的相似但不完全相同:
class FFunctor x where
ffmap :: (f ~> g) -> (x f ~> x g)
但是,在您的情况下,x f
和x g
不是仿函数,x f -> x g
是正常函数而不是自然转换。尽管如此,这种模式还是足够吸引人的。
考虑到这一点,似乎x
仍然是一个仿函数的例子,只是在两个不同的类别之间。它从Functors类别到具有不同结构的x
类别。每个可能的x
,如Foo
,都会形成一个类别,其中包含Foo []
和Foo Maybe
等对象以及它们之间的转换(Foo [] -> Foo Maybe
)。您的interleaveHomomorphism
函数会将自然变换“提升”到这些x-morphisms
中,就像fmap
“将”正常(a -> b
)函数提升到仿函数图像中的函数一样({{ 1}})。
所以是的:你的类型类似于f a -> f b
的仿函数,除了两个不同的类别之外。我不知道它的具体名称,主要是因为我不知道像Functor
这样的结构的具体名称。
更一般地说,我甚至不确定具体名称是否有意义。在这一点上,我们可能想要一个很好的通用仿函数类型类,它位于任何两个类别之间。也许是这样的:
x
这可能已经存在于某个库中。
不幸的是,这种定义不同仿函数的特殊方法需要一堆额外的新类型噪声,因为class (Category catA, Category catB) => GFunctor f catA catB where
gfmap :: catA a b -> catB (f a) (f b)
已经是一个类别。事实上,让所有类型正确排列将会有点痛苦。
所以将它称为(->)
或其他东西可能最容易。此外,想象一下pun potential!
编辑:看起来XFunctor
提供了CFunctor
这样的类型,但有点聪明:
categories
然而,我不确定即使这样也足够普遍!我认为我们可能希望它在类型上更具多态性。
答案 1 :(得分:0)
Bar f
看起来像Free Monad Free f ()
。
然后Foo
是do
,其中包含一个或两个<-
。也许从那里继续......
答案 2 :(得分:0)
对于它的价值,您可以将示例的简化版本改为
data Bar' r = Zero | Succ r
type Bar f = fix (Bar' . f)
对于每对自然变换eta1 :: f ~> g
和eta2 :: Bar' ~> h
,我们得到自然变换(eta2 . eta1) :: (Bar' . f) ~> (h . g)
。我们可以通过显而易见的方式在固定点上解除这种自然转换,以获得fixed (eta2 . eta1) :: Bar f -> fix (h . g)
。因此,你的&#34;交错同态&#34;当我们有eta2 = id
时,这只是这种结构的一个特例。
总的来说,这是一个相当标准的结构(特别是对于f
是monad或comonad的情况),虽然我不确定它是否具有被广泛认可的特定名称。