P.S. I think you can also leave a trailing comma in Rust, and with the code layout as above, it means you can easily swap the positions of lines in an editor using CTRL+arrow up/down. I sometimes wish that first and last lines in syntax lists in Elm were not special.
As far as I know, there is no default. The common JSON encoder/decoder Poison will reject a tuple as input, since it cannot be injectively encoded to JSON (and back).
This is an interesting question though; I’ll ask the Elixir community for more input on this.
Related to this discussion is this great set of answers on the Software Engineering StackExchange, about representing Tagged Union types (AKA sum types) in OOP languages:
That is interesting. The mapping of List to C# given there is:
interface List<A> {
B Match<B>(B nil, Func<A, List<A>, B> cons);
}
class Nil<A> : List<A> {
public Nil() {}
public B Match<B>(B nil, Func<A, List<A>, B> cons) {
return nil;
}
}
class Cons<A> : List<A> {
private readonly A head;
private readonly List<A> tail;
public Cons(A head, List<A> tail) {
this.head = head;
this.tail = tail;
}
public B Match<B>(B nil, Func<A, List<A>, B> cons) {
return cons(head, tail);
}
}
So to do a pattern match, you pass in a pair of functions, and depending if its a nil or cons one of the functions gets called.
I have used this style in Elm, where I had an opaque type, so the consumer could not pattern match on it.
In Elm this would look like:
module OpaqueList exposing (List, match)
type List a
= Nil
| Cons a (List a)
match : b -> (a -> List a -> b) -> List a -> b
match nilFn consFn xs =
case xs of
Nil -> nilFn
Cons head tail -> consFn head tail
The empty list is always the same [] so I just left the argument off. nilFn isn’t really a function, its a constant, so perhaps I should just have called it nilVal.