Advertisement
tinyevil

Untitled

Mar 3rd, 2018
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.09 KB | None | 0 0
  1. #include <functional>
  2. #include <vector>
  3. #include <iostream>
  4.  
  5. template< template<class> class M >
  6. class Monad{
  7. public:
  8. template<class A>
  9. static M<A> Return(A a);
  10.  
  11. template<class A, class B>
  12. static M<B> Bind(M<A> a, std::function<M<B>(A)> f);
  13. };
  14.  
  15. template<class A>
  16. class Unit{};
  17.  
  18. template<>
  19. class Monad<Unit> {
  20. public:
  21. template<class A>
  22. static Unit<A> Return(A a){
  23. return Unit<A>();
  24. }
  25.  
  26. template<class A, class B>
  27. static Unit<B> Bind(Unit<A> a, std::function<Unit<B>(A)> f){
  28. return Unit<B>();
  29. }
  30. };
  31.  
  32. template<class A>
  33. struct Id{
  34. A a;
  35. };
  36.  
  37. template<>
  38. class Monad<Id> {
  39. public:
  40. template<class A>
  41. static Id<A> Return(A a){
  42. return {a};
  43. }
  44.  
  45. template<class A, class B>
  46. static Id<B> Bind(Id<A> a, std::function<Id<B>(A)> f){
  47. return f(a.a);
  48. }
  49. };
  50.  
  51. template<class A>
  52. struct Maybe{
  53. A* a;
  54. };
  55.  
  56. template<>
  57. class Monad<Maybe> {
  58. public:
  59. template<class A>
  60. static Maybe<A> Return(A a){
  61. return {new A(a)};
  62. }
  63.  
  64. template<class A, class B>
  65. static Maybe<B> Bind(Id<A> a, std::function<Maybe<B>(A)> f){
  66. if ( a.a ){
  67. return f(*a.a);
  68. }
  69. return {nullptr};
  70. }
  71. };
  72.  
  73.  
  74. template<class T>
  75. using List = std::vector<T>;
  76.  
  77. template<>
  78. class Monad<List> {
  79. public:
  80. template<class A>
  81. static List<A> Return(A a){
  82. return {a};
  83. }
  84.  
  85. template<class A, class B>
  86. static List<B> Bind(List<A> a, std::function<List<B>(A)> f){
  87. List<B> out;
  88. for ( auto& x : a ){
  89. List<B> b = f(x);
  90. for ( auto& y : b ){
  91. out.push_back(y);
  92. }
  93. }
  94. return out;
  95. }
  96. };
  97.  
  98.  
  99. List<int> WithLists(){
  100. using M = Monad<List>;
  101.  
  102. List<int> xs = {1, 2, 3};
  103. List<int> ys = {5, 6, 7};
  104.  
  105. return M::Bind<int,int>(xs, [&](int x){
  106. return M::Bind<int,int>(ys, [&](int y){
  107. return M::Return(x * y);
  108. });
  109. });
  110. }
  111.  
  112.  
  113.  
  114. int main(){
  115. List<int> xs = WithLists();
  116. std::cout << "[";
  117. for ( auto& x : xs ){
  118. std::cout << x << " ";
  119. }
  120. std::cout << "]\n";
  121.  
  122. return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement