Note that there are some explanatory texts on larger screens.

plurals
  1. POCan I constrain a type family?
    primarykey
    data
    text
    <p>In <a href="https://stackoverflow.com/a/14132830/828361">this recent answer of mine</a>, I happened to crack open this old chestnut (a program so old, half of it was written in the seventeenth century by Leibniz and written on a computer in the seventies by my dad). I'll leave out the modern bit to save space.</p> <pre><code>class Differentiable f where type D f :: * -&gt; * 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 :&amp;: 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) =&gt; Differentiable (f :+: g) where type D (f :+: g) = D f :+: D g instance (Differentiable f, Differentiable g) =&gt; Differentiable (f :*: g) where type D (f :*: g) = (D f :*: g) :+: (f :*: D g) </code></pre> <p>Now, here's the frustrating thing. I don't know how to stipulate that <code>D f</code> must <em>itself</em> be differentiable. Certainly, these instances respect that property, and there might well be fun programs you can write which make use of the ability to keep differentiating a functor, shooting holes in more and more places: Taylor expansions, that sort of thing.</p> <p>I'd like to be able to say something like</p> <pre><code>class Differentiable f where type D f instance Differentiable (D f) </code></pre> <p>and require a check that instance declarations have <code>type</code> definitions for which the necessary instances exist.</p> <p>Maybe more mundane stuff like</p> <pre><code>class SortContainer c where type WhatsIn c instance Ord (WhatsIn c) ... </code></pre> <p>would also be nice. That, of course, has the fundep workaround</p> <pre><code>class Ord w =&gt; SortContainer c w | c -&gt; w where ... </code></pre> <p>but to attempt the same trick for <code>Differentiable</code> seems... well... involuted.</p> <p>So, is there a nifty workaround that gets me repeatable differentiability? (I guess I could build a representation GADT and and and... but is there a way that works with classes?)</p> <p>And are there any obvious snags with the suggestion that we should be able to demand constraints on type (and, I suppose, data) families when we declare them, then check that the instances satisfy them?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. COWhy do you need this? Can't you just specify the constraint at the call site? Also, is there any reason that `D f` must be repeatedly differentiable like this? It's not a requirement of derivatives (in the mathematical sense) in general, and I don't see why it's a precondition for a valid derivative in this particular setting either.
      singulars
    2. COI want to characterize infinite differentiability, so I can write programs which might make arbitrarily many holes in data. In classical real analysis, there are functions with wonky corners which are not infinitely differentiable, but it's not obvious how to build these things with parametric types. But you're right that there's no reason to assume that differentiable things are infinitely differentiable. Infinite differentiability is still a desirable thing to capture.
      singulars
    3. CO@JohnL: In a sense, it's not logically a *constraint* here--any type constructed from products, sums, `()`, `Void`, `I`, and `K` in this fashion corresponds to a polynomial, and will be infinitely differentiable for the same reasons those are--you'll eventually get `K Void` or something equivalent, which is a fixed point of the derivative. The quandary here is not about requiring an additional property, it's about telling GHC that a particular property will always hold for all valid instances.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload