我正在寻找具有以下属性的Haskell类型 A (使用异国情调的GHC扩展对我来说很好......):对于所有可遍历的 t ,以下两种类型是同构的:
forall a. C a => t a -> a
和
t A -> A.
在我的具体情况中,C是以下类:
class Floating a => C a where
fromDouble :: Double -> a
换句话说,我想以某种方式将所有类型 a 在 C 中的通用量化纳入 A 类型,所以函数t A - >; A给了我一个所有 a的功能。所以我想我正在寻找某种意义上的C级“通用”实例......
我已经考虑了 A 的各种花哨定义,
newtype A = A (forall b. C b => b)
或
data A = forall b. C b => A b
或
newtype A = A (forall t b. (Traversable t, C b) => t b -> b),
或
data A = FromDouble Double | Plus A A | Tanh A | ...
甚至
data A = A (forall t. Traversable t => t A -> A),
并且它们都可以很容易地成为C类的实例,但它们没有我需要的属性(或者至少我没有看到如何从我上面的任何定义中获取该属性)。
在奇怪的日子里,我确信A型根本就不存在,即使在相反的日子里我也确信相反......
...所以任何帮助都会受到高度赞赏!
为我的问题提供一些动力:我非常依赖于Edward Kmett's ad library neural networks library,在我的第一次尝试中,我使用他的Numeric.AD.Rank1.Kahn类型进行自动区分和反向传播。这导致了一个不错的API,但效率低于他的反向模式,遗憾的是,我在问题中使用量化来编码可微分函数。
我希望我可以拥有两个世界中最好的 - 一个特定的(抽象)类型加上反向模式效率。
答案 0 :(得分:12)
让我们假设这样一个普遍的"类型Service
存在。
A
是可遍历的,因此我们得到了
Const ()
即。之间(因为forall a. C a => Const () a -> a
-- and
Const () A -> A
与Const () a
同构,而()
与() -> b
同构)
b
因此,如果存在任何forall a. C a => a
-- and
A
,则它必须与A
同构。
请注意,这是您首次尝试解决方案 - 如果这不符合要求,那么什么都不会。
现在,根据您的具体情况
forall a. C a => a
粗略地表示,根据forall a. C a => a
(*)的定义[注意:这里我错了"遗忘" C
超类,整个论证更加脆弱]
Floating a
与forall a. (Double -> a) -> a
:
Double
证明上述实际上是同构是非平凡的 - 我认为它需要一些参数,如"Recursive types for free!"。 (Yoneda的后果?......评论欢迎!)
所以 - 如果有一个解决方案,对于你的iso :: Double -> forall a. (Double -> a) -> a
iso x f = f x
osi :: (forall a. (Double -> a) -> a) -> Double
osi f = f id
,它必须是C
,直到同构。
(*)我在这里伸展了一些东西。我不知道如何精确处理Haskell的有限量化,所以我采用明确的字典,即使我猜它也不完全一样。