Skip to content

Instantly share code, notes, and snippets.

@milesrout
Last active May 29, 2016 05:20
Show Gist options
  • Save milesrout/6f43b30522a3fd914120 to your computer and use it in GitHub Desktop.
Save milesrout/6f43b30522a3fd914120 to your computer and use it in GitHub Desktop.
Alvin, a language similar to Haskell

In Haskell the trivial type is written as () and has kind ∗. The list type is written as [] and has kind ∗→∗, which means that it is sort of a 'metafunction' from type to type. Applying [] (kind ∗→∗) to Int (kind ∗) gives [] Int i.e. [Int] (kind ∗). The function type is written as (->) and has kind ∗→∗→∗ i.e. ∗→(∗→∗) which means it's a sort of metafunction from type to a function from type to type. Applying (->) (kind ∗→∗→∗) to Int (kind ∗) gives (->) Int (kind ∗→∗), and applying that to Float (kind ∗) gives (->) Int Float i.e. Int -> Float (kind ∗).

In Alvin the trivial type is written as Trivial. The list type is written as List. It is a template, taking a type and 'returning' a type. Applying List to Int gives List::value<Int>. The function type is written as Function. (->) Int is written as Function::value<Int> and Int -> Float is written as Function::value<Int>::value<Float>.

Haskell:

  • 1 is a value of type Int.
  • 1.0 is a value of type Float.
  • [] is a value of type [].
  • 1:[] is a value of type [] Int i.e. [Int].
  • 1:2:3:[] is a value of type [] Int i.e. [Int].
  • After weird x = [x, 1], weird is a value of type (->) Int ([] Int) i.e. Int -> [Int].

Alvin:

  • Int::value<1> is a value of type Int.
  • Float::value<1.0> is a value of type Float.
  • EmptyList::value<T> is a value of type List::value<T>.
  • Cons::value<Int::value<1>>::value<EmptyList<Int>> is a value of type List::value<Int>.
  • Cons::value<Int::value<1>>::value<Cons::value<Int::value<2>>::value<Cons::value<Int::value<3>::value<EmptyList::value<Int>>>> is a value of type List::value<Int>.
  • After class Weird { template <typename T> using value = Cons::of<T>::with<Cons::of<Int::value<1>>::with<EmptyList::value<Int>>>; };, Weird is a value of type Function::from<Int>::to<List::of<Int>>.

It's a little more verbose than Haskell.

// these are 'special constructors', they don't have types. they aren't Alvin values, they're basically magic literal helpers.
// just like in the '1.0f' literal in C++, f doesn't have a type. It's just syntax. These are just syntax.
struct Int {
template <int i>
struct value {
using type = Int;
};
};
struct Float {
template <float f>
struct value {
using type = Float;
};
};
struct EmptyList {
template <typename T>
struct value {
using type = List::value<T>;
};
};
// what is the type of `(:)` ? forall x. x -> [x] -> [x]
// what is the type of `(:) 1` ? [Int] -> [Int]
// what is the type of `(:) 1 []` ? [Int]
struct cons {
template <typename x>
using of = value<x>;
template <typename x>
struct value {
template <typename x>
using with = value<x>;
template <typename y>
struct value {
using type = List::of<x::type>;
};
using type = Function::from<List::of<x::type>>::to<List::of<x::type>>;
};
template <typename T>
using type = Function::from<T>::to<Function::from<List::of<T>>::to<List::of<T>>>;
}
struct Function {
template <typename arg>
using from = value<arg>;
template <typename arg>
struct value {
template <typename ret>
using to = value<ret>;
template <typename ret>
struct value {
using type = Star;
};
using type = Function::from<Star>::to<Star>;
};
using type = Function::from<Star>::to<Function::from<Star>::to<Star>>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment