Можно ли эмулировать функциональность класса классов Haskell с шаблонами С++ (или С#)?
Имеет ли смысл или есть ли какой-либо выигрыш в этом?
Я пытался создать класс Functor на С++, и я не смог. Я пробовал что-то вроде этого:
#include <iostream>
using namespace std;
//A function class to make types more readable
template <class input, class output> class Function {
private:
output (*ptrfunc )(input);
public:
Function(output (* ptr)(input)) {
ptrfunc = ptr;
}
output call(input x) {return (*ptrfunc)(x);}
output operator() (input x) { return call(x);}
};
//the functor "typeclass"
template <class a> class Functor{
public:
template <class b> Functor<b> fmap(Function<a,b> func);
};
// an container type to be declared "instance" of functor:
template <class a> class List : public Functor<a> {
private:
a * ptrList;
int size;
public:
List(int n) { //constructor;
ptrList = new a[n];
size = n;
}
List(List<a> const& other) { //copy constructor
size = other.size;
ptrList = new a[size];
for(int i = 0; i<size; i++)
(*this)[i] = other[i];
}
~List() { delete ptrList;} //destructor
a& operator[](int i) { return ptrList[i];} // subscript operator just for easy notation
const a& operator[](int i) const { return ptrList[i];}// subscript operator just for easy notation
template <class b> List<b> fmap(Function<a,b> func) { //"instance" version of fmap
List<b> temp(size);
for(int i = 0; i < size; i++)
temp[i] = func((*this)[i]);
return temp;
}
};
int test(int k) { return 2 * k;}
int main(void) {
Function<int, int> func(&test);
List<int> lista(10);
for(int i = 0; i < 10; i++)
lista[i] = i;
List<int> lista2(lista.fmap(func));
for(int i = 0; i < 10; i++)
cout << lista2[i] << " ";
cout << endl;
return 0;
}
Он делает то, что он должен делать, но имеет ли смысл использовать этот шаблон в С++? Это действительно тот же шаблон, что и в haskell:
data List a = -- some stuff
class Functor f where
fmap :: (a -> b) -> f a -> f b
instance (Functor List) where
-- some stuff
Мне кажется, что это не то же самое, потому что в Functor f
, f
является конструктором типа * -> *
типа, а в моем определении выше в Functor<a>
, a
не является template a<something>
, но сам "содержащийся" тип данных.
Есть ли выход из этого? И что еще более важно: имеет смысл попытаться скопировать эти шаблоны на С++? Мне кажется, что С# больше похож на функциональный стиль программирования, чем на С++. Есть ли способ сделать это в С#?