在我最近的回答中,我碰巧打开了这个旧栗子(一个如此古老的程序,其中一半是莱布尼茨在 17 世纪编写的,而我父亲在 70 年代在计算机上编写的)。我将省略现代部分以节省空间。
class Differentiable f where
type D f :: * -> *
newtype K a x = K a
newtype I x = I x
data (f :+: g) x = L (f x)
| R (g x)
data (f :*: g) x = f x :&: g x
instance Differentiable (K a) where
type D (K a) = K Void
instance Differentiable I where
type D I = K ()
instance (Differentiable f, Differentiable g) => Differentiable (f :+: g) where
type D (f :+: g) = D f :+: D g
instance (Differentiable f, Differentiable g) => Differentiable (f :*: g) where
type D (f :*: g) = (D f :*: g) :+: (f :*: D g)
现在,令人沮丧的事情来了。我不知道如何规定它本身D f
必须是可微的。当然,这些实例尊重该属性,并且很可能您可以编写有趣的程序,这些程序利用不断区分函子的能力,在越来越多的地方射孔:泰勒展开式,诸如此类。
我希望能够说类似的话
class Differentiable f where
type D f
instance Differentiable (D f)
并要求检查实例声明是否具有type
存在必要实例的定义。
也许更平凡的东西,比如
class SortContainer c where
type WhatsIn c
instance Ord (WhatsIn c)
...
也会很好。当然,这有 fundep 解决方法
class Ord w => SortContainer c w | c -> w where ...
但尝试同样的把戏Differentiable
似乎……嗯……内卷。
那么,是否有一个很好的解决方法可以让我获得可重复的微分性?(我想我可以构建一个表示 GADT 和 and and ......但是有没有一种方法可以与类一起使用?)
并且当我们声明它们时,我们应该能够要求对类型(以及,我想,数据)族进行约束,然后检查实例是否满足它们的建议,是否有任何明显的障碍?