Created
May 3, 2015 07:10
-
-
Save wecing/172ace00a4ea807215d4 to your computer and use it in GitHub Desktop.
Sum and Product monoid in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdlib> | |
#include <memory> | |
#include <vector> | |
#include <string> | |
template<typename M, typename T> | |
class SemiGroup { | |
protected: | |
T m_t; | |
public: | |
SemiGroup(T t) : m_t(t) {} | |
SemiGroup<M,T> mappend(SemiGroup<M,T> other); | |
T get() { return m_t; } | |
}; | |
template<typename M, typename T> | |
class Monoid : public SemiGroup<M,T> { | |
public: | |
Monoid(T t) : SemiGroup<M,T>(t) {} | |
static Monoid<M,T> mzero; | |
}; | |
class Sum {}; | |
template<> | |
SemiGroup<Sum, int> SemiGroup<Sum, int>::mappend(SemiGroup<Sum, int> other) { | |
return SemiGroup<Sum, int>(m_t + other.m_t); | |
} | |
template<> | |
Monoid<Sum, int> Monoid<Sum, int>::mzero = Monoid<Sum, int>(0); | |
class Product {}; | |
template<> | |
SemiGroup<Product, int> SemiGroup<Product, int>::mappend(SemiGroup<Product, int> other) { | |
return SemiGroup<Product, int>(m_t * other.m_t); | |
} | |
template<> | |
Monoid<Product, int> Monoid<Product, int>::mzero = Monoid<Product, int>(1); | |
template<typename M, typename T> | |
Monoid<M, T> mconcat(const std::vector<T> & vals) { | |
Monoid<M, T> r = Monoid<M, T>::mzero; | |
for (auto v : vals) { | |
r = Monoid<M, T>(r.mappend(v).get()); | |
} | |
return r; | |
} | |
int main(void) { | |
std::vector<int> vals{3, 5}; | |
std::cout << "Sum::mconcat [3,5] == " | |
<< mconcat<Sum,int>(vals).get() | |
<< std::endl; | |
std::cout << "Product::mconcat [3,5] == " | |
<< mconcat<Product,int>(vals).get() | |
<< std::endl; | |
return 0; | |
} |
darkfall
commented
May 3, 2015
(心悦诚服(但是你的写法比我的长啊))@darkfall
(睡前意识模糊状态下的, 其实没啥卵区别, 除了variadic template可以传任意多个参数进去而不用构造list, 几个模板单独出来个人觉得扩展比较方便, 这样就不用偏特化你的类而是几个trait模板(不用在意那些细节( @wecing
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment