In Idris/Haskell, one can prove properties of data by annotating the types and using GADT constructors, such as with Vect, however, this requires hardcoding the property into the type (e.g. a Vect has to be a separate type from a List). Is it possible to have types with an open set of properties (such as list carrying both a length and running average), for example by overloading constructors or using something in the vein of Effect?
相关问题
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
- Haskell split a list into two by a pivot value
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Top-level expression evaluation at compile time
- Stuck in the State Monad
- foldr vs foldr1 usage in Haskell
- List of checkboxes with digestive-functors
- How does this list comprehension over the inits of
- Replacing => in place of -> in function type signa
I believe that McBride has answered that question (for Type Theory) in his ornament paper (pdf). The concept you are looking for is the one of an algebraic ornament (emphasis mine):
Now, let's write some code. I've put the whole thing in a gist because I'm going to interleave comments in here. Also, I'm using Agda but it should be easy to tranlate to Idris.
We start by defining what it means to be an algebra delivering
B
s acting on a list ofA
s. We need a base case (a value of typeB
) as well as way to combine the head of the list with the induction hypothesis.Given this definition, we can define a type of lists of
A
s indexed byB
s whose value is precisely the result of the computation corresponding to a givenListAlg A B
. In thenil
case, the result is the base case provided to us by the algebra (proj₁ alg
) whilst in thecons
case, we simply combine the induction hypothesis with the new head using the second projection:Ok, let's import some libraries and see a couple of examples now:
The algebra computing the length of a list is given by
0
as the base case andconst suc
as the way to combine anA
and the length of the tail to build the length of the current list. Hence:If the elements are natural numbers then they can be summed. The algebra corresponding to that has
0
as the base case and_+_
as the way to combine anℕ
together with the sum of the elements contained in the tail. Hence:Crazy thought: If we have two algebras working on the same elements, we can combine them! This way we'll track 2 invariants rather than one!
An now the examples:
If we are tracking the length, then we can define Vectors:
And have, e.g., this vector of length 4:
If we are tracking the sum of the elements, then we can define a notion of distribution: a statistical distribution is a list of probabilities whose sum is 100:
And we can define a uniform one for instance:
Finally, by combining the length and sum algebras, we can implement the notion of sized distribution.
And give this nice uniform distribution for a 4 elements set: