Skip to content

Instantly share code, notes, and snippets.

@milesrout
Last active August 29, 2015 14:07
Show Gist options
  • Save milesrout/79a13ce75cfb0886bc9f to your computer and use it in GitHub Desktop.
Save milesrout/79a13ce75cfb0886bc9f to your computer and use it in GitHub Desktop.
data Natural = Zero | Succ Natural
add :: Natural -> Natural -> Natural
add Zero b = b
add (Succ a) b = add a (Succ b)
mul :: Natural -> Natural -> Natural
mul Zero _ = Zero
mul _ Zero = Zero
mul (Succ a) b = add b (mul a b)
struct Zero {};
template <typename a>
struct Succ {};
// determine if a type is a natural number
template <typename a>
struct Natural;
template <>
struct Natural<Zero> {
using type = true_t;
};
template <typename a>
struct Natural<Succ<a>> {
using type = Natural<a>::type;
};
// addition
template <typename a, typename b>
struct add;
template <typename b, typename = Natural<b>>
struct add<Zero, b> {
using type = b;
};
template <typename a, typename b,
typename = Natural<a>, typename = Natural<b>>
struct add<Succ<a>, b> {
using type = add<a, Succ<b>>::type;
};
// multiplication
template <typename a, typename b>
struct mul;
template <typename a, typename = Natural<a>>
struct mul<Zero, a> {
using type = Zero;
};
template <typename a, typename = Natural<a>>
struct mul<a, Zero> {
using type = Zero;
};
template <typename a, typename b,
typename = Natural<a>, typename = Natural<b>>
struct mul<Succ<a>, b> {
using type = add<b, mul<a, b>::type>::type;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment