Типы высшего класса с C ++ - PullRequest
43 голосов
/ 02 апреля 2010

Этот вопрос предназначен для людей, которые знают как Haskell (или любой другой функциональный язык, поддерживающий типы с более высоким родом), так и C ++ ...

Можно ли моделировать типы с более высоким родом, используя шаблоны C ++? Если да, то как?

РЕДАКТИРОВАТЬ:

С это представление Тони Морриса:

Полиморфизм высшего порядка:

  • Такие языки, как Java и C #, имеют полиморфизм первого порядка, потому что они позвольте нам абстрагироваться от типов. например List<A> может иметь функцию reverse который работает на любом типе элемента ( A).

  • Более практичные языки программирования и системы типов позволяют нам Аннотация на конструкторы типа как хорошо.

  • Эта функция называется высшего порядка (или более выраженный) полиморфизм.

Пример:

Псевдо-Java с придуманной нотацией для полиморфизма высшего порядка

interface Transformer<X, Y> {
  Y transform(X x);
}

interface Monad<M> { // M :: * -> *
  <A> M<A> pure(A a);
  <A, B> M<B> bind(Transformer<A, M<B>> t, M<A> a);
}

Ответы [ 2 ]

62 голосов
/ 02 апреля 2010

Параметры шаблона-шаблона?

template <template <typename> class m>
struct Monad {
    template <typename a>
    static m<a> mreturn(const a&);

    template <typename a, typename b>
    static m<b> mbind(const m<a>&, m<b>(*)(const a&));
};

template <typename a>
struct Maybe {
    bool isNothing;
    a value;
};

template <>
struct Monad<Maybe> {
    template <typename a>
    static Maybe<a> mreturn(const a& v) {
        Maybe<a> x;
        x.isNothing = false;
        x.value = v;
        return x;
    }

    template <typename a, typename b>
    static Maybe<b> mbind(const Maybe<a>& action, Maybe<b>(*function)(const a&)) {
        if (action.isNothing)
            return action;
        else
            return function(action.value);
    }
};
3 голосов
/ 02 апреля 2010

Обычно нормальный шаблон не является типом с более высоким родом?Например, std::vector принимает параметр типа для создания фактического типа, такого как std::vector<int>, поэтому он имеет вид * -> *.

...