migmit: (Default)
[personal profile] migmit

Вот есть хаскельный код (пример упрощён до предела):

data P a = P a (forall b. b -> P (a, b))
Нормально компилится, если указать прагму LANGUAGE RankNTypes в GHC или ключик -98 в Hugs-е.
Можно написать несколько "генераторов" для такого P:
sameValue :: a -> P a
sameValue x = P x (\y -> sameValue (x, y))

firstRest :: a -> a -> P a
firstRest x y = P x (\z -> sameValue (y, z))

switching :: a -> a -> P a
switching x y = P x (\z -> switching (y, z) (x, z))
Как сделать это на C++???
Я попробовал, моего плюс-фу не хватило. Светилы, если вы есть, можете подсказать?
Хочется что-то вроде этого:

#include <map>
template <class A> class P {
  A car;
  template <class B> virtual P<std::pair<A,B> > cdr (B) = 0;
};

Не заработает, ибо template и virtual вместе не живут. Убрать virtual нельзя - класс определяется как абстрактный, реализация функции cdr будет разной (см. выше), но эту разницу надо скрыть "под капотом", указывая везде базовый класс.
Как?

Originally posted on migmit.vox.com

Date: 2009-02-06 06:34 am (UTC)
From: [identity profile] migmit.vox.com (from livejournal.com)
Про P.P.S.: Вообще-то я работал на хаскеле. У меня был некий код, который работал для любого класса C (скажем, для класса Ord, или Eq), для которого имеется инстанс (C a, C b) => C (a,b). То есть, если типы a и b относятся к классу C, то пара из них - тоже, автоматически. Абстрагировать класс в хаскеле нельзя, поэтому я попытался сделать тип, для которого что-то подобное содержится в нём самом:
  a   ( a) (forall b  b   (a, b))
Ну и просто заинтересовался, можно ли перенести соответствующую идиому в C++. К спискам типов оно отношения не имеет.