Extensible records using type indexed lists are my favourite method at the
moment, although we looked at lots in the HList and OOHaskell papers.
Dealing elegantly with the kinds of problems covered in those two papers is
one of the main things that made me want to develop a language.

You can define a base record:

data R = R {
   a :: String
}

Some possible extra bits:

data S1 = S1 {
   b :: Int
}

data S2 = S2 {
   c :: Float
}

And some type synonyms, which are not necessary but show the types of the
combined records.

type T1 = R :+: S1
type T2 = R :+: S2

Extracting records happens by type indexing so:

t = R {a = "ABC"} :+: S1 {b = 1}

t.a = "ABC"
t.b = 1

:+: is both the type level and value level constrictor (overloaded) for the
type - indexed - lists.

Keean.
On 30 May 2015 16:40, "Jonathan S. Shapiro" <s...@eros-os.org> wrote:

> I want to try to "unpack" something I hinted at the other day in the AST
> thread. This may be a well-known thing that I simply haven't stumbled
> across. It could also just be a bad idea.
>
> Original problem: I want to build an AST in which the parent/child
> constraints are described by statically described type relations in a
> closed union. There are many **non-variant** fields to this AST. There
> appears to be no good way to describe this type in languages that cleanly
> separate product, record, and union types. So far as I can tell, the
> possible solutions are:
>
> 1. Add an element to every union leg for the non-variant part.
> 2. Make the union an element of the non-variant part, and check for sanity
> dynamically (e.g. using a checking procedure).
>
> From a language design perspective, there seem to be two possible ways to
> deal with this sort of pattern:
>
> 1. Allow non-variant fields
>
> The first - the simple one - is simply to allow unions to have non-variant
> parts. Semantically, this is the same as adding a "reference to invariant
> part" to every leg, but it is textually much simpler. Because it's simple,
> it's probably the right approach for now, and I think it's generally useful
> to have non-variant parts mixed with variant parts.
>
> There are some examples of data structures in C that exploit the absence
> of tags to do something even more interesting: specify variant parts that
> are *intermingled* with the non-variant parts. Usually this is done for the
> sake of layout, or for the sake of matching some externally specified
> message layout. Once again, I don't think this changes the semantics of
> union types.
>
> 2. Support type-indexed types explicitly
>
> This approach is suggested by the AST<T> idea that somebody put forward.
> The idea here is that T is a leg type of some union. So AST<T = expr> might
> have a field "children: T", and the corresponding union leg definition
> might be something like:
>
> union ASTTree  ....
>   expr : e1 : AST<mulexpr>, e2 : AST<mulexpr>
>
> What happens here is that the recursiveness of the type gets "threaded"
> through the AST type by means of the parameter type. Depending on your
> point of view, the AST.expr field can be viewed has having type "expr"
> (which is a leg type of ASTTree) or might have type ASTTree. In this
> intuition, I'm viewing "expr" as a subtype of ASTree.
>
> The two parts of this that are a bit unusual are that the type AST< T <:
> ASTTree > and the type ASTTree are co-recursively defined, so we probably
> end up needing something similar to letrec for this definition. Perhaps
> typerec?
>
> Anyway, this is the general sort of intuition that I was groping for. I
> wanted to describe it a bit more clearly so that people could ponder it and
> react if they wish.
>
>
> shap
>
> _______________________________________________
> bitc-dev mailing list
> bitc-dev@coyotos.org
> http://www.coyotos.org/mailman/listinfo/bitc-dev
>
>
_______________________________________________
bitc-dev mailing list
bitc-dev@coyotos.org
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to