├── .gitignore ├── README.html ├── README.md ├── docs ├── func-idioms-c++.pdf ├── func-idioms-c++.tex ├── func-idioms-c++.toc ├── pp-fp-1.pdf ├── pp-fp-1.tex ├── pp-fp-2.pdf └── pp-fp-2.tex ├── html ├── cmsy10-c-46.png ├── cmsy10-c-4c.png ├── cmsy10-c-5a.png ├── func-idioms-c++.css ├── func-idioms-c++.html ├── func-idioms-c++0x.png ├── func-idioms-c++10x.png ├── func-idioms-c++11x.png ├── func-idioms-c++12x.png ├── func-idioms-c++13x.png ├── func-idioms-c++14x.png ├── func-idioms-c++15x.png ├── func-idioms-c++16x.png ├── func-idioms-c++1x.png ├── func-idioms-c++2x.png ├── func-idioms-c++3x.png ├── func-idioms-c++4x.png ├── func-idioms-c++5x.png ├── func-idioms-c++6x.png ├── func-idioms-c++7x.png ├── func-idioms-c++8x.png └── func-idioms-c++9x.png └── src ├── applicative_functor.cpp ├── applicative_functor.hpp ├── bind.cpp ├── bracket.cpp ├── bracket.hpp ├── bracket_helper.hpp ├── curry.cpp ├── curry.hpp ├── curry_helper.hpp ├── either.cpp ├── either.hpp ├── either_monad.cpp ├── either_monad.hpp ├── fold.hpp ├── forward_zip_list.hpp ├── functor.cpp ├── functor.hpp ├── future_value.cpp ├── future_value.hpp ├── future_value_monad.cpp ├── future_value_monad.hpp ├── lambda.cpp ├── list_of_ptr.hpp ├── main.cpp ├── makefile ├── map.cpp ├── map.hpp ├── maybe.cpp ├── maybe.hpp ├── maybe_monad.cpp ├── maybe_monad.hpp ├── monad.cpp ├── monad.hpp ├── mpc.cpp ├── mpc.hpp ├── proto.hpp ├── raw_pointer.hpp ├── rpl ├── show.hpp ├── snippets.txt ├── state.cpp ├── state.hpp ├── state_monad.cpp ├── state_monad.hpp ├── thunk.cpp ├── thunk.hpp ├── trans.cpp ├── unary_op.hpp ├── value_pack.hpp ├── w.cpp ├── w.hpp ├── zip.hpp └── zip_list.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *# 3 | .#* 4 | *.o 5 | *.abcl 6 | *.lx64fsl 7 | *.fasl 8 | .DS_Store 9 | build/ 10 | obj/ 11 | bin/ 12 | *.aux 13 | *.log 14 | *.gz 15 | *dvi 16 | *idv 17 | *4ct 18 | *aux 19 | *log 20 | *tc 21 | *xref 22 | *lg 23 | *tmp 24 | -------------------------------------------------------------------------------- /README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 193 | 194 |

Functional Programming in C++

195 | 196 |

Overview

197 | 198 |

This repository contains my attempt to explore basic functional programming in C.

199 | 200 |

Why

201 | 202 |

What

203 | 204 |

WhatEver

205 | 206 |

Building

207 | 208 |

Documents

209 | 210 |

Basic Functional Programming

211 | 212 |

Applicative Functors

213 | 214 |

Monads

215 | 216 | 217 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Functional Programming in C++ 3 | 4 | ## Overview 5 | 6 | This repository contains my attempt to explore basic functional programming in C++. 7 | It builds on the availability of λ's and variadic templates (among other things). 8 | 9 | One self-imposed limitation was to avoid `weird`syntax or to overload operators away from their semantics. 10 | 11 | The goal is to provide some examples of the us of functional techniques in C++ using existing language features and libraries. 12 | 13 | This does not cover template meta-programming in case you were wondering. 14 | 15 | ### Why 16 | It's a great way to explore functional programming and C++, neither of which are well served by this approach. 17 | 18 | I primarily use it as a test bench and don't intend to turn this into some sort of library. 19 | 20 | 21 | ###Build 22 | 23 | 1. Use the latest version of gcc.I've build this with gcc 4.8 on mac osx 10.8.4. 24 | 2. Clone the repo. 25 | 3. Run make in the src directory. 26 | 4. run ../bin/main or ../bin/main all 27 | 5. ../bin/main is a very primitive 'repl' which allows you to run the test functions. 28 | 29 | ### What 30 | 31 | #### ./src 32 | 33 | The main file in the source directory contains a 'repl' and a set of registered test functions. 34 | 35 | The .cpp files contain simple example code for the functional concepts in the header. 36 | So bracket.cpp contains example code for bracket.hpp and bracket_helper.hpp 37 | 38 | #### ./docs 39 | 40 | This directory contains .tex files. These document provide more background for the code. 41 | pp-fp-1.tex discusses basic functional programming available in C++. pp-fp-2.tex discusses more advanced concepts. 42 | 43 | pp-fp-1.tex was submitted to pragpub for publication. 44 | 45 | ### Related Work 46 | I've been able to track down two articles which discuss functional programming in C++. 47 | 48 | 1. Work by Yannis and McNamara circa early 2000 49 | 2. Work by David Sankel circa 2010. 50 | 51 | Yannis and McNamara develop a library using C++ as it existed circa 2000. Interesting, but you need to stay within their framework. 52 | 53 | Sankel uses boost to implement advanced functional programming concepts in C++. 54 | 55 | ## Functional Programming 56 | 57 | ### Basics 58 | 59 | #### Immutability 60 | 61 | #### Higher Order Functions 62 | Combine functions to construct other functions 63 | 64 | #### Currying 65 | 66 | Turn any function into a unary higher order function 67 | 68 | #### Map 69 | 70 | Apply a function to a list of values 71 | 72 | #### Reduce 73 | 74 | Apply a function to a list of values and accumulate the result. 75 | 76 | ### Advanced 77 | 78 | #### Functors 79 | 80 | Generalizes maps for data "containers" other than lists. 81 | 82 | #### Applicative Functors 83 | 84 | Enables pure functions to be used in a "container" 85 | 86 | #### Bracket Notation 87 | 88 | 89 | 90 | #### Monads 91 | 92 | ### Helpful Hints 93 | 94 | #### Books 95 | 96 | ##### C++ 97 | 98 | 1. [The C++ Programming Language; 4th ed.](http://www.stroustrup.com/4th.html) 99 | 2. [The C++ Standard Library; 2nd ed.](http://www.cppstdlib.com/) 100 | 101 | 102 | ##### Functional Programming 103 | 104 | 105 | #### Articles 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/func-idioms-c++.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/docs/func-idioms-c++.pdf -------------------------------------------------------------------------------- /docs/func-idioms-c++.toc: -------------------------------------------------------------------------------- 1 | \contentsline {section}{\numberline {1}Introduction}{3} 2 | \contentsline {subsection}{\numberline {1.1}Functional Programming}{3} 3 | \contentsline {subsection}{\numberline {1.2}Support in C++}{3} 4 | \contentsline {subsection}{\numberline {1.3}Conventions and Notation}{3} 5 | \contentsline {section}{\numberline {2}Functional Idioms}{3} 6 | \contentsline {subsection}{\numberline {2.1}Introduction}{3} 7 | \contentsline {subsection}{\numberline {2.2}Currying}{4} 8 | \contentsline {subsection}{\numberline {2.3}Functor}{5} 9 | \contentsline {subsection}{\numberline {2.4}Applicative Functors and Brackets}{6} 10 | \contentsline {subsubsection}{\numberline {2.4.1}Applicatives}{6} 11 | \contentsline {subsubsection}{\numberline {2.4.2}Brackets}{7} 12 | \contentsline {subsection}{\numberline {2.5}Monads}{7} 13 | \contentsline {section}{\numberline {3}The Functional Idioms in C++}{7} 14 | \contentsline {subsection}{\numberline {3.1}General Approach}{7} 15 | \contentsline {subsection}{\numberline {3.2}Currying}{8} 16 | \contentsline {subsection}{\numberline {3.3}Functor}{8} 17 | \contentsline {subsection}{\numberline {3.4}Applicative Functor and Brackets}{8} 18 | \contentsline {subsubsection}{\numberline {3.4.1}Applicative}{8} 19 | \contentsline {subsubsection}{\numberline {3.4.2}Bracket}{8} 20 | \contentsline {subsection}{\numberline {3.5}Monad}{9} 21 | \contentsline {subsection}{\numberline {3.6}What's Next}{10} 22 | \contentsline {section}{\numberline {4}Maybe}{10} 23 | \contentsline {subsection}{\numberline {4.1}Motivation}{10} 24 | \contentsline {subsection}{\numberline {4.2}Maybe Template Class}{10} 25 | \contentsline {subsection}{\numberline {4.3}Functor}{12} 26 | \contentsline {subsection}{\numberline {4.4}Applicative Functor}{14} 27 | \contentsline {subsection}{\numberline {4.5}Monad}{14} 28 | \contentsline {section}{\numberline {5}Either}{16} 29 | \contentsline {subsection}{\numberline {5.1}Motivation}{16} 30 | \contentsline {subsection}{\numberline {5.2}Either Type Class}{16} 31 | \contentsline {subsection}{\numberline {5.3}Functor}{19} 32 | \contentsline {subsection}{\numberline {5.4}Applicative Functor}{20} 33 | \contentsline {subsection}{\numberline {5.5}Monad}{22} 34 | \contentsline {section}{\numberline {6}Lists and ZipLists}{23} 35 | \contentsline {subsection}{\numberline {6.1}Lists in the C++ Standard Library}{23} 36 | \contentsline {subsection}{\numberline {6.2}Functor}{23} 37 | \contentsline {subsection}{\numberline {6.3}Applicative Functor}{25} 38 | \contentsline {subsubsection}{\numberline {6.3.1}List}{25} 39 | \contentsline {subsubsection}{\numberline {6.3.2}ZipList}{26} 40 | \contentsline {subsection}{\numberline {6.4}Brackets}{27} 41 | \contentsline {subsection}{\numberline {6.5}Monad}{27} 42 | \contentsline {section}{\numberline {7}Shared Pointers}{28} 43 | \contentsline {subsection}{\numberline {7.1}Pointers and Shared pointers}{28} 44 | \contentsline {subsection}{\numberline {7.2}Functor}{28} 45 | \contentsline {subsection}{\numberline {7.3}Applicative Functor}{30} 46 | \contentsline {subsection}{\numberline {7.4}Monad}{30} 47 | \contentsline {section}{\numberline {8}List of Shared Pointers}{31} 48 | \contentsline {subsection}{\numberline {8.1}Functor}{31} 49 | \contentsline {subsection}{\numberline {8.2}Applicative Functor}{31} 50 | \contentsline {subsection}{\numberline {8.3}Monad}{33} 51 | \contentsline {section}{\numberline {9}Unary Operations}{33} 52 | \contentsline {subsection}{\numberline {9.1}Unary Operations and Curried Functions}{33} 53 | \contentsline {subsection}{\numberline {9.2}Functor}{33} 54 | \contentsline {subsection}{\numberline {9.3}Applicative Functor}{34} 55 | \contentsline {subsection}{\numberline {9.4}Monad}{34} 56 | \contentsline {section}{\numberline {10}Stateful Computations}{34} 57 | \contentsline {subsection}{\numberline {10.1}Capturing State}{34} 58 | \contentsline {subsection}{\numberline {10.2}Functor}{37} 59 | \contentsline {subsection}{\numberline {10.3}Applicative Functor}{39} 60 | \contentsline {subsection}{\numberline {10.4}Monad}{40} 61 | \contentsline {section}{\numberline {11}Futures and Future Values}{42} 62 | \contentsline {subsection}{\numberline {11.1}Futures and Async}{42} 63 | \contentsline {subsection}{\numberline {11.2}Capturing Future Values}{42} 64 | \contentsline {subsection}{\numberline {11.3}Functor}{43} 65 | \contentsline {subsection}{\numberline {11.4}Monad}{45} 66 | \contentsline {section}{\numberline {12}Discussion}{47} 67 | -------------------------------------------------------------------------------- /docs/pp-fp-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/docs/pp-fp-1.pdf -------------------------------------------------------------------------------- /docs/pp-fp-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/docs/pp-fp-2.pdf -------------------------------------------------------------------------------- /html/cmsy10-c-46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/cmsy10-c-46.png -------------------------------------------------------------------------------- /html/cmsy10-c-4c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/cmsy10-c-4c.png -------------------------------------------------------------------------------- /html/cmsy10-c-5a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/cmsy10-c-5a.png -------------------------------------------------------------------------------- /html/func-idioms-c++.css: -------------------------------------------------------------------------------- 1 | 2 | /* start css.sty */ 3 | .cmss-12{ font-family: sans-serif;} 4 | .cmss-12{ font-family: sans-serif;} 5 | .cmss-12{ font-family: sans-serif;} 6 | .cmss-12{ font-family: sans-serif;} 7 | .cmss-12{ font-family: sans-serif;} 8 | .cmss-12{ font-family: sans-serif;} 9 | .cmss-12{ font-family: sans-serif;} 10 | .cmss-12{ font-family: sans-serif;} 11 | .cmss-12{ font-family: sans-serif;} 12 | .cmss-12{ font-family: sans-serif;} 13 | .cmss-17x-x-120{font-size:170%; font-family: sans-serif;} 14 | .cmss-17x-x-120{ font-family: sans-serif;} 15 | .cmss-17x-x-120{ font-family: sans-serif;} 16 | .cmss-17x-x-120{ font-family: sans-serif;} 17 | .cmss-17x-x-120{ font-family: sans-serif;} 18 | .cmss-17x-x-120{ font-family: sans-serif;} 19 | .cmss-17x-x-120{ font-family: sans-serif;} 20 | .cmss-17x-x-120{ font-family: sans-serif;} 21 | .cmss-17x-x-120{ font-family: sans-serif;} 22 | .cmss-17x-x-120{ font-family: sans-serif;} 23 | .cmss-12x-x-120{font-size:120%; font-family: sans-serif;} 24 | .cmss-12x-x-120{ font-family: sans-serif;} 25 | .cmss-12x-x-120{ font-family: sans-serif;} 26 | .cmss-12x-x-120{ font-family: sans-serif;} 27 | .cmss-12x-x-120{ font-family: sans-serif;} 28 | .cmss-12x-x-120{ font-family: sans-serif;} 29 | .cmss-12x-x-120{ font-family: sans-serif;} 30 | .cmss-12x-x-120{ font-family: sans-serif;} 31 | .cmss-12x-x-120{ font-family: sans-serif;} 32 | .cmss-12x-x-120{ font-family: sans-serif;} 33 | .cmss-10x-x-109{font-size:90%; font-family: sans-serif;} 34 | .cmss-10x-x-109{ font-family: sans-serif;} 35 | .cmss-10x-x-109{ font-family: sans-serif;} 36 | .cmss-10x-x-109{ font-family: sans-serif;} 37 | .cmss-10x-x-109{ font-family: sans-serif;} 38 | .cmss-10x-x-109{ font-family: sans-serif;} 39 | .cmss-10x-x-109{ font-family: sans-serif;} 40 | .cmss-10x-x-109{ font-family: sans-serif;} 41 | .cmss-10x-x-109{ font-family: sans-serif;} 42 | .cmss-10x-x-109{ font-family: sans-serif;} 43 | .cmssbx-10x-x-109{font-size:90%; font-family: sans-serif; font-weight: bold;} 44 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 45 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 46 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 47 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 48 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 49 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 50 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 51 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 52 | .cmssbx-10x-x-109{ font-family: sans-serif; font-weight: bold;} 53 | .cmr-8{font-size:66%;} 54 | .cmmi-12{font-style: italic;} 55 | .cmmi-8{font-size:66%;font-style: italic;} 56 | .cmmi-6{font-size:50%;font-style: italic;} 57 | .cmsy-8{font-size:66%;} 58 | .cmsy-6{font-size:50%;} 59 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 60 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 61 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 62 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 63 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 64 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 65 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 66 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 67 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 68 | .cmssi-12{ font-family: sans-serif; font-style: oblique;} 69 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 70 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 71 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 72 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 73 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 74 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 75 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 76 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 77 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 78 | .cmssbx-10x-x-120{ font-family: sans-serif; font-weight: bold;} 79 | .cmss-8x-x-75{font-size:50%; font-family: sans-serif;} 80 | .cmss-8x-x-75{ font-family: sans-serif;} 81 | .cmss-8x-x-75{ font-family: sans-serif;} 82 | .cmss-8x-x-75{ font-family: sans-serif;} 83 | .cmss-8x-x-75{ font-family: sans-serif;} 84 | .cmss-8x-x-75{ font-family: sans-serif;} 85 | .cmss-8x-x-75{ font-family: sans-serif;} 86 | .cmss-8x-x-75{ font-family: sans-serif;} 87 | .cmss-8x-x-75{ font-family: sans-serif;} 88 | .cmss-8x-x-75{ font-family: sans-serif;} 89 | .cmssbx-10x-x-60{font-size:50%; font-family: sans-serif; font-weight: bold;} 90 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 91 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 92 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 93 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 94 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 95 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 96 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 97 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 98 | .cmssbx-10x-x-60{ font-family: sans-serif; font-weight: bold;} 99 | .cmssi-8x-x-75{font-size:50%; font-family: sans-serif; font-style: oblique;} 100 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 101 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 102 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 103 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 104 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 105 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 106 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 107 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 108 | .cmssi-8x-x-75{ font-family: sans-serif; font-style: oblique;} 109 | p.noindent { text-indent: 0em } 110 | td p.noindent { text-indent: 0em; margin-top:0em; } 111 | p.nopar { text-indent: 0em; } 112 | p.indent{ text-indent: 1.5em } 113 | @media print {div.crosslinks {visibility:hidden;}} 114 | a img { border-top: 0; border-left: 0; border-right: 0; } 115 | center { margin-top:1em; margin-bottom:1em; } 116 | td center { margin-top:0em; margin-bottom:0em; } 117 | .Canvas { position:relative; } 118 | img.math{vertical-align:middle;} 119 | li p.indent { text-indent: 0em } 120 | li p:first-child{ margin-top:0em; } 121 | li p:last-child, li div:last-child { margin-bottom:0.5em; } 122 | li p~ul:last-child, li p~ol:last-child{ margin-bottom:0.5em; } 123 | .enumerate1 {list-style-type:decimal;} 124 | .enumerate2 {list-style-type:lower-alpha;} 125 | .enumerate3 {list-style-type:lower-roman;} 126 | .enumerate4 {list-style-type:upper-alpha;} 127 | div.newtheorem { margin-bottom: 2em; margin-top: 2em;} 128 | .obeylines-h,.obeylines-v {white-space: nowrap; } 129 | div.obeylines-v p { margin-top:0; margin-bottom:0; } 130 | .overline{ text-decoration:overline; } 131 | .overline img{ border-top: 1px solid black; } 132 | td.displaylines {text-align:center; white-space:nowrap;} 133 | .centerline {text-align:center;} 134 | .rightline {text-align:right;} 135 | div.verbatim {font-family: monospace; white-space: nowrap; text-align:left; clear:both; } 136 | .fbox {padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; } 137 | div.fbox {display:table} 138 | div.center div.fbox {text-align:center; clear:both; padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; } 139 | div.minipage{width:100%;} 140 | div.center, div.center div.center {text-align: center; margin-left:1em; margin-right:1em;} 141 | div.center div {text-align: left;} 142 | div.flushright, div.flushright div.flushright {text-align: right;} 143 | div.flushright div {text-align: left;} 144 | div.flushleft {text-align: left;} 145 | .underline{ text-decoration:underline; } 146 | .underline img{ border-bottom: 1px solid black; margin-bottom:1pt; } 147 | .framebox-c, .framebox-l, .framebox-r { padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; } 148 | .framebox-c {text-align:center;} 149 | .framebox-l {text-align:left;} 150 | .framebox-r {text-align:right;} 151 | span.thank-mark{ vertical-align: super } 152 | span.footnote-mark sup.textsuperscript, span.footnote-mark a sup.textsuperscript{ font-size:80%; } 153 | div.tabular, div.center div.tabular {text-align: center; margin-top:0.5em; margin-bottom:0.5em; } 154 | table.tabular td p{margin-top:0em;} 155 | table.tabular {margin-left: auto; margin-right: auto;} 156 | td p:first-child{ margin-top:0em; } 157 | td p:last-child{ margin-bottom:0em; } 158 | div.td00{ margin-left:0pt; margin-right:0pt; } 159 | div.td01{ margin-left:0pt; margin-right:5pt; } 160 | div.td10{ margin-left:5pt; margin-right:0pt; } 161 | div.td11{ margin-left:5pt; margin-right:5pt; } 162 | table[rules] {border-left:solid black 0.4pt; border-right:solid black 0.4pt; } 163 | td.td00{ padding-left:0pt; padding-right:0pt; } 164 | td.td01{ padding-left:0pt; padding-right:5pt; } 165 | td.td10{ padding-left:5pt; padding-right:0pt; } 166 | td.td11{ padding-left:5pt; padding-right:5pt; } 167 | table[rules] {border-left:solid black 0.4pt; border-right:solid black 0.4pt; } 168 | .hline hr, .cline hr{ height : 1px; margin:0px; } 169 | .tabbing-right {text-align:right;} 170 | span.TEX {letter-spacing: -0.125em; } 171 | span.TEX span.E{ position:relative;top:0.5ex;left:-0.0417em;} 172 | a span.TEX span.E {text-decoration: none; } 173 | span.LATEX span.A{ position:relative; top:-0.5ex; left:-0.4em; font-size:85%;} 174 | span.LATEX span.TEX{ position:relative; left: -0.4em; } 175 | div.float, div.figure {margin-left: auto; margin-right: auto;} 176 | div.float img {text-align:center;} 177 | div.figure img {text-align:center;} 178 | .marginpar {width:20%; float:right; text-align:left; margin-left:auto; margin-top:0.5em; font-size:85%; text-decoration:underline;} 179 | .marginpar p{margin-top:0.4em; margin-bottom:0.4em;} 180 | table.equation {width:100%;} 181 | .equation td{text-align:center; } 182 | td.equation { margin-top:1em; margin-bottom:1em; } 183 | td.equation-label { width:5%; text-align:center; } 184 | td.eqnarray4 { width:5%; white-space: normal; } 185 | td.eqnarray2 { width:5%; } 186 | table.eqnarray-star, table.eqnarray {width:100%;} 187 | div.eqnarray{text-align:center;} 188 | div.array {text-align:center;} 189 | div.pmatrix {text-align:center;} 190 | table.pmatrix {width:100%;} 191 | span.pmatrix img{vertical-align:middle;} 192 | div.pmatrix {text-align:center;} 193 | table.pmatrix {width:100%;} 194 | span.bar-css {text-decoration:overline;} 195 | img.cdots{vertical-align:middle;} 196 | .partToc a, .partToc, .likepartToc a, .likepartToc {line-height: 200%; font-weight:bold; font-size:110%;} 197 | .index-item, .index-subitem, .index-subsubitem {display:block} 198 | div.caption {text-indent:-2em; margin-left:3em; margin-right:1em; text-align:left;} 199 | div.caption span.id{font-weight: bold; white-space: nowrap; } 200 | h1.partHead{text-align: center} 201 | p.bibitem { text-indent: -2em; margin-left: 2em; margin-top:0.6em; margin-bottom:0.6em; } 202 | p.bibitem-p { text-indent: 0em; margin-left: 2em; margin-top:0.6em; margin-bottom:0.6em; } 203 | .paragraphHead, .likeparagraphHead { margin-top:2em; font-weight: bold;} 204 | .subparagraphHead, .likesubparagraphHead { font-weight: bold;} 205 | .quote {margin-bottom:0.25em; margin-top:0.25em; margin-left:1em; margin-right:1em; text-align:justify;} 206 | .verse{white-space:nowrap; margin-left:2em} 207 | div.maketitle {text-align:center;} 208 | h2.titleHead{text-align:center;} 209 | div.maketitle{ margin-bottom: 2em; } 210 | div.author, div.date {text-align:center;} 211 | div.thanks{text-align:left; margin-left:10%; font-size:85%; font-style:italic; } 212 | div.author{white-space: nowrap;} 213 | .quotation {margin-bottom:0.25em; margin-top:0.25em; margin-left:1em; } 214 | .abstract p {margin-left:5%; margin-right:5%;} 215 | div.abstract {width:100%;} 216 | .lstlisting .label{margin-right:0.5em; } 217 | div.lstlisting{font-family: monospace; white-space: nowrap; margin-top:0.5em; margin-bottom:0.5em; } 218 | div.lstinputlisting{ font-family: monospace; white-space: nowrap; } 219 | .lstinputlisting .label{margin-right:0.5em;} 220 | /* end css.sty */ 221 | 222 | -------------------------------------------------------------------------------- /html/func-idioms-c++0x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++0x.png -------------------------------------------------------------------------------- /html/func-idioms-c++10x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++10x.png -------------------------------------------------------------------------------- /html/func-idioms-c++11x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++11x.png -------------------------------------------------------------------------------- /html/func-idioms-c++12x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++12x.png -------------------------------------------------------------------------------- /html/func-idioms-c++13x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++13x.png -------------------------------------------------------------------------------- /html/func-idioms-c++14x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++14x.png -------------------------------------------------------------------------------- /html/func-idioms-c++15x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++15x.png -------------------------------------------------------------------------------- /html/func-idioms-c++16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++16x.png -------------------------------------------------------------------------------- /html/func-idioms-c++1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++1x.png -------------------------------------------------------------------------------- /html/func-idioms-c++2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++2x.png -------------------------------------------------------------------------------- /html/func-idioms-c++3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++3x.png -------------------------------------------------------------------------------- /html/func-idioms-c++4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++4x.png -------------------------------------------------------------------------------- /html/func-idioms-c++5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++5x.png -------------------------------------------------------------------------------- /html/func-idioms-c++6x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++6x.png -------------------------------------------------------------------------------- /html/func-idioms-c++7x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++7x.png -------------------------------------------------------------------------------- /html/func-idioms-c++8x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++8x.png -------------------------------------------------------------------------------- /html/func-idioms-c++9x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fons/functional-cpp/193f423e737b52389a6db356da47a74e587857c7/html/func-idioms-c++9x.png -------------------------------------------------------------------------------- /src/applicative_functor.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "w.hpp" 4 | #include "applicative_functor.hpp" 5 | #include "list_of_ptr.hpp" 6 | #include "forward_zip_list.hpp" 7 | #include "zip_list.hpp" 8 | 9 | int apf_1() 10 | { 11 | 12 | std::function show =[](W w) { w.pp(std::cerr) << std::endl; return w.ssn();}; 13 | 14 | auto p = applicative_functor::pure(W(1090867, "hello_kitty")); 15 | auto s = applicative_functor::pure(show); 16 | std::cout << p << std::endl; 17 | applicative_functor::fmap(show)(p); 18 | applicative_functor::apply(s)(p); 19 | 20 | return 0; 21 | } 22 | 23 | 24 | int apf_2() 25 | { 26 | 27 | std::forward_list K = {2, 5, 10}; 28 | std::forward_list L = {8, 10, 11}; 29 | std::function show = [=](int v) { 30 | std::cout << v << ","; 31 | return v; 32 | }; 33 | std::function < std::function < int (int) > (int)> plus = [] (int x) { 34 | return [=] (int y) { 35 | return x + y; 36 | }; 37 | }; 38 | 39 | auto ls = applicative_functor::pure(show); 40 | auto lp = applicative_functor::pure(plus); 41 | auto kl = applicative_functor::apply(lp)(K); 42 | auto M = applicative_functor::apply(kl)(L); 43 | 44 | applicative_functor::apply(ls)(K); 45 | std::cout << std::endl; 46 | applicative_functor::apply(ls)(L); 47 | std::cout << std::endl; 48 | applicative_functor::apply(ls)(M); 49 | std::cout << std::endl; 50 | 51 | return 0; 52 | } 53 | 54 | int apf_3() 55 | { 56 | auto val2 = applicative_functor::pure(56); 57 | std::cout << " pure (56) : "<< val2(89) << std::endl; 58 | 59 | auto val3 = applicative_functor::pure(56); 60 | std::cout << " pure (56) : "<< val3(8990) << std::endl; 61 | 62 | return 0; 63 | } 64 | 65 | int apf_4() 66 | { 67 | std::function f = [] (int x, int y) { return x + y + 5 ;}; 68 | std::function g = [] (int x) { return x * 400;}; 69 | auto res = applicative_functor::apply(f,g); 70 | std::cout << " val : " << res(3) << std::endl; 71 | return 0; 72 | } 73 | 74 | int apf_5() 75 | { 76 | std::function f = [] (int x, int y) { return x + y + 5 ;}; 77 | std::function g = [] (int x) { return x * 400;}; 78 | 79 | auto res = applicative_functor::apply(f)(g); 80 | std::cout << " val : " << res(3) << std::endl; 81 | return 0; 82 | } 83 | 84 | int apf_6() 85 | { 86 | 87 | std::function(int)> plus = [=] (int x) { 88 | return [=] (int y) { 89 | return x + y; 90 | }; 91 | }; 92 | 93 | std::function(int)> mult = [] (int x) { 94 | return [=] (int y) { 95 | return x * y; 96 | }; 97 | }; 98 | 99 | auto m100 = mult(100); 100 | auto pl3 = plus(3); 101 | 102 | std::cout << "pl3 : " << pl3(90) << std::endl; 103 | 104 | auto r = functor::fmap(plus,pl3); 105 | 106 | std::cout << " val : " << r(3)(3) << std::endl; 107 | 108 | std::function uncur = [&r](int x, int y) { return r(x)(y);}; 109 | 110 | std::cout << "uncur : " << uncur(3,3) << " compare : " << r(3)(3) << std::endl; 111 | 112 | auto res = applicative_functor::apply(uncur, m100); 113 | std::cout << " res : " << res(5) << std::endl; 114 | 115 | return 0; 116 | } 117 | 118 | int apf_7() 119 | { 120 | 121 | std::function(int)> plus = [=] (int x) { 122 | return [=] (int y) { 123 | return x + y; 124 | }; 125 | }; 126 | 127 | std::function(int)> mult = [] (int x) { 128 | return [=] (int y) { 129 | return x * y; 130 | }; 131 | }; 132 | 133 | auto m100 = mult(100); 134 | auto pl3 = plus(3); 135 | 136 | std::cout << "pl3 : " << pl3(90) << std::endl; 137 | 138 | auto r = functor::fmap(plus,pl3); 139 | 140 | std::cout << " val : " << r(3)(3) << std::endl; 141 | 142 | auto res2 = applicative_functor::apply(r, m100); 143 | std::cout << " res2 : " << res2(5) << std::endl; 144 | 145 | return 0; 146 | } 147 | 148 | int apf_8() 149 | { 150 | 151 | std::function(int)> plus = [=] (int x) { 152 | return [=] (int y) { 153 | return x + y; 154 | }; 155 | }; 156 | 157 | std::function(int)> mult = [] (int x) { 158 | return [=] (int y) { 159 | return x * y; 160 | }; 161 | }; 162 | 163 | auto m100 = mult(100); 164 | auto pl3 = plus(3); 165 | 166 | std::cout << "pl3 : " << pl3(90) << std::endl; 167 | 168 | auto res2 = applicative_functor::apply(functor::fmap(plus,pl3), m100); 169 | std::cout << " res2 : " << res2(5) << std::endl; 170 | 171 | return 0; 172 | } 173 | typedef int (FP)(int); 174 | 175 | int fgy(int x) 176 | { 177 | return 200*x-99; 178 | } 179 | 180 | int apf_9() 181 | { 182 | typedef std::tuple W; 183 | std::forward_list> L = {std::shared_ptr{new W(10, "a")}, std::shared_ptr{new W(20, "b")}, std::shared_ptr{new W(3467, "mnhjk")}}; 184 | std::function show =[](const W& w) { std::cerr << w << std::endl; return w;}; 185 | auto lifted_show = applicative_functor::pure(applicative_functor::apply(applicative_functor::pure(show))); 186 | applicative_functor::apply(lifted_show)(L); 187 | 188 | return 0; 189 | } 190 | 191 | int apf_10() 192 | { 193 | forward_list_of_ptr L = {std::make_shared(5),std::make_shared(15),std::make_shared(25),std::make_shared(35)}; 194 | auto f = [](const int& c) { std::cerr << c << ","; return c;}; 195 | functor::fmap(f)(L); 196 | std::cerr << std::endl; 197 | auto y = applicative_functor::pure(45); 198 | auto lifted_lambda = applicative_functor::pure(f); 199 | applicative_functor::apply(lifted_lambda)(L); 200 | std::cerr << std::endl; 201 | applicative_functor::apply(lifted_lambda)(y); 202 | std::cerr << std::endl; 203 | return 0; 204 | } 205 | 206 | 207 | int apf_11() 208 | { 209 | forward_zip_list L = {2, 5, 10}; 210 | auto f = [](const int& c) { std::cerr << c << ","; return c;}; 211 | functor::fmap(f)(L); 212 | std::cerr << std::endl; 213 | 214 | auto y = applicative_functor::pure(45); 215 | auto lifted_lambda = applicative_functor::pure(f); 216 | 217 | applicative_functor::apply(lifted_lambda)(L); 218 | std::cerr << std::endl; 219 | applicative_functor::apply(lifted_lambda)(y); 220 | std::cerr << std::endl; 221 | return 0; 222 | } 223 | 224 | int apf_12() 225 | { 226 | 227 | std::list L = {2, 5, 10}; 228 | auto f = [](const int& c) { std::cerr << c << ","; return c;}; 229 | 230 | functor::fmap(f)(L); 231 | std::cerr << std::endl; 232 | 233 | auto lifted_lambda_1 = applicative_functor::pure(f); 234 | applicative_functor::apply(lifted_lambda_1)(L); 235 | std::cerr << std::endl; 236 | 237 | auto lifted_lambda = applicative_functor::pure(f); 238 | applicative_functor::apply(lifted_lambda)(L); 239 | std::cerr << std::endl; 240 | auto y = applicative_functor::pure(45); 241 | applicative_functor::apply(lifted_lambda)(y); 242 | std::cerr << std::endl; 243 | 244 | return 0; 245 | } 246 | 247 | 248 | int apf_13() 249 | { 250 | std::function f = [](int x){ return 45*x - 89;}; 251 | auto F = applicative_functor::pure(f); 252 | auto V = new int (56); 253 | auto res = applicative_functor::apply(F, V); 254 | std::cerr << "V : " << *V << "==> " << *res << std::endl; 255 | return 0; 256 | } 257 | 258 | int apf_14() 259 | { 260 | std::function f = [](int x){ return 45*x - 89;}; 261 | auto F = applicative_functor::pure([](int x){ return 45*x - 89;}); 262 | auto V = new int (56); 263 | auto res = applicative_functor::apply(F, V); 264 | 265 | std::cerr << "V : " << *V << "==> " << *res << std::endl; 266 | 267 | return 0; 268 | } 269 | -------------------------------------------------------------------------------- /src/applicative_functor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__applicative_functor__h 2 | #define h__applicative_functor__h 3 | 4 | #include "functor.hpp" 5 | 6 | template class F> 7 | struct applicative_functor : public functor 8 | { 9 | 10 | template 11 | static F pure(A val); 12 | 13 | template 14 | static std::function < F (F)> apply(F > f ); 15 | }; 16 | 17 | template<> 18 | struct applicative_functor : public functor 19 | { 20 | 21 | template 22 | static std::shared_ptr pure(A val) { 23 | return std::make_shared(val); 24 | } 25 | 26 | 27 | template 28 | static std::function< std::shared_ptr (std::shared_ptr v)> apply(std::shared_ptr> f) { 29 | return [f](std::shared_ptr v) { 30 | if (v && f) { 31 | auto F = *f; 32 | return pure (F(*v)); 33 | } 34 | return std::shared_ptr(nullptr); 35 | }; 36 | } 37 | 38 | template 39 | static std::function< std::shared_ptr (std::shared_ptr v)> apply(std::shared_ptr f) { 40 | return [f](std::shared_ptr v) { 41 | if (v && f) { 42 | auto F = *f; 43 | return pure (F(*v)); 44 | } 45 | return std::shared_ptr(nullptr); 46 | }; 47 | } 48 | 49 | }; 50 | 51 | 52 | template<> struct 53 | applicative_functor :public functor{ 54 | 55 | template 56 | static std::forward_list pure(A v) { 57 | return std::forward_list(1,v); 58 | } 59 | 60 | template 61 | static std::function< std::forward_list (std::forward_list)> apply(std::forward_list> F) { 62 | return [F](std::forward_list L) { 63 | std::forward_list acc; 64 | for (auto& func : F) { 65 | for (auto& arg : L) { 66 | acc.push_front(func(arg)); 67 | } 68 | } 69 | acc.reverse(); 70 | return acc; 71 | }; 72 | }; 73 | 74 | template 75 | static std::function< std::forward_list (std::forward_list)> apply(std::forward_list F) { 76 | return [F](std::forward_list L) { 77 | std::forward_list acc; 78 | for (auto& func : F) { 79 | for (auto& arg : L) { 80 | acc.push_front(func(arg)); 81 | } 82 | } 83 | acc.reverse(); 84 | return acc; 85 | }; 86 | }; 87 | 88 | }; 89 | 90 | template<> 91 | struct applicative_functor : public functor 92 | { 93 | 94 | template 95 | static std::function pure(B val) { 96 | return [val] (A x) { 97 | return val; 98 | }; 99 | }; 100 | 101 | template 102 | static std::function apply(std::function < R (A,B)> f, std::function g) { 103 | return [f,g] (A x) { 104 | return f(x, g(x)); 105 | }; 106 | }; 107 | 108 | template 109 | static std::function apply(std::function< std::function(A) > f, std::function g) { 110 | return [f,g] (A x) { 111 | return f(x)(g(x)); 112 | }; 113 | }; 114 | 115 | template 116 | static std::function< std::function (std::function)> apply(std::function < R (A,B)> f) { 117 | return [f] (std::function g) -> std::function { 118 | std::function G(g); 119 | return [f,G] (A x) { 120 | return f(x, G(x)); 121 | }; 122 | }; 123 | }; 124 | 125 | }; 126 | 127 | template<> struct 128 | applicative_functor :public functor{ 129 | 130 | template 131 | static std::list pure(A v) { 132 | std::list L; 133 | L.push_front(v); 134 | return L; 135 | } 136 | 137 | template 138 | static std::function< std::list (std::list)> apply(std::list> F) { 139 | return [F](std::list L) { 140 | std::list acc; 141 | for (auto& func : F) { 142 | for (auto& arg : L) { 143 | acc.push_back(func(arg)); 144 | } 145 | } 146 | return acc; 147 | }; 148 | }; 149 | 150 | 151 | template 152 | static std::function< std::list (std::list)> apply(std::list F) { 153 | return [F](std::list L) { 154 | std::list acc; 155 | for (auto& func : F) { 156 | for (auto& arg : L) { 157 | acc.push_back(func(arg)); 158 | } 159 | } 160 | return acc; 161 | }; 162 | }; 163 | 164 | }; 165 | 166 | template<> 167 | struct applicative_functor : public functor 168 | { 169 | 170 | template 171 | static A* pure(A val) { 172 | return new A(val); 173 | } 174 | 175 | 176 | template 177 | static std::function apply(std::function* f) { 178 | return [f](A* v) { 179 | if (v && f) { 180 | auto F = *f; 181 | return pure (F(*v)); 182 | } 183 | return static_cast(nullptr); 184 | }; 185 | } 186 | 187 | template 188 | static B* apply(std::function* f, A* v) { 189 | return apply(f)(v); 190 | } 191 | 192 | template 193 | static std::function apply(lambda* f) { 194 | return [f](A* v) { 195 | if (v && f) { 196 | auto F = *f; 197 | return pure (F(*v)); 198 | } 199 | return static_cast(nullptr); 200 | }; 201 | }; 202 | 203 | template 204 | static B* apply(lambda* f, A* v) { 205 | return apply(f)(v); 206 | } 207 | }; 208 | 209 | 210 | 211 | #endif 212 | -------------------------------------------------------------------------------- /src/bind.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | 3 | using namespace std; 4 | using namespace std::placeholders; 5 | 6 | int bind_1() 7 | { 8 | 9 | auto l = std::bind(plus(), _1, 10); 10 | cout << l(902) << endl; 11 | return 0; 12 | } 13 | 14 | int bind_2() 15 | { 16 | 17 | auto l = std::bind([=](int x, int y){return 5 * x + y; }, _1, 10); 18 | cout << l(902) << endl; 19 | return 0; 20 | } 21 | 22 | // Bind is not curry... 23 | int bind_3() 24 | { 25 | 26 | auto l = std::bind([=](int x, int y){return 5 * x + y; }, _2, _1); 27 | auto r = l(10, 8); 28 | cout << r << endl; 29 | return 0; 30 | } 31 | 32 | int bind_4() 33 | { 34 | auto multi = [](int x, int y) { return x*y;}; 35 | auto repeat = [](int n, int x) { int y = 1; 36 | while (n-- > 0) y *= x; 37 | return y;}; 38 | 39 | auto rpl = std::bind (repeat, 40 | std::placeholders::_1, 41 | std::bind(multi, 42 | std::placeholders::_2, 43 | std::placeholders::_3)); 44 | 45 | std::cout << " multi (10,2) : " << multi(10,2) << std::endl; 46 | std::cout << " repeat (2,2) : " << repeat(2,2) << std::endl; 47 | auto val = rpl(4, 1, 2); //( 1 * 2) ^ 4 48 | std::cout << " result : " << val << std::endl; 49 | return 0; 50 | } 51 | 52 | 53 | int bind_5() 54 | { 55 | std::function l1 = [](double x) { return 2*x-0.906;}; 56 | auto repeat = [](int n, double y, std::function f) { 57 | while (n-- > 0) { 58 | y = f(y); 59 | } 60 | return y; 61 | }; 62 | 63 | auto rpl = std::bind (repeat, 64 | std::placeholders::_1, 65 | std::placeholders::_1, 66 | std::placeholders::_2); 67 | 68 | auto val = rpl(9, l1); // print 4145.03 69 | std::cout << " result : " << val << std::endl; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/bracket.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "functor.hpp" 3 | #include "applicative_functor.hpp" 4 | #include "show.hpp" 5 | #include "curry.hpp" 6 | #include "bracket.hpp" 7 | #include "list_of_ptr.hpp" 8 | #include "forward_zip_list.hpp" 9 | #include "zip_list.hpp" 10 | 11 | //ways to set up the bracket notation.. 12 | 13 | 14 | int bracket_1() 15 | { 16 | std::forward_list L = {1,2,3}; 17 | std::function f = [] (int a) { return 2*a;}; 18 | 19 | auto K = functor::fmap(f, L); 20 | std::cout << L << std::endl; 21 | std::cout << K << std::endl; 22 | 23 | std::function ff = [] (int a, int b) { return 2*a + 10*b;}; 24 | 25 | // 0 : curry ff 26 | auto cff = curry(ff); 27 | //1.. fmap cury_ff L 28 | auto C = functor::fmap(cff, L); 29 | //2.. 30 | auto J = applicative_functor::apply(C)(K); 31 | 32 | std::cout << J << std::endl; 33 | 34 | return 0; 35 | } 36 | 37 | /* 38 | Remember this ?? 39 | --[1,2] >>= \x->['a','b']>>= \ch->return (x,ch) 40 | 41 | refC = bracket 42 | n <- [1,2] 43 | ch <- ['a','b'] 44 | return (n, ch) 45 | 46 | */ 47 | 48 | int bracket_2() 49 | { 50 | std::forward_list L = {1,2}; 51 | std::forward_list K = {'a','b'}; 52 | 53 | 54 | typedef int T1; 55 | typedef char T2; 56 | 57 | auto ff = [] (T1 a, T2 b) { return std::make_tuple(a,b);}; 58 | 59 | // 0 : curry ff 60 | 61 | auto cff = curry(ff); 62 | 63 | //1.. lift cury_ff L 64 | auto cffl = applicative_functor::pure(cff); 65 | //2 apply applicative 66 | auto C = applicative_functor::apply(cffl)(L); 67 | //3.. apply applicative 68 | auto J = applicative_functor::apply(C)(K); 69 | 70 | std::cout << J << std::endl; 71 | 72 | return 0; 73 | } 74 | 75 | 76 | template using m_t = std::forward_list; 77 | 78 | int bracket_3() 79 | { 80 | typedef int T1; 81 | typedef char T2; 82 | typedef std::string T3; 83 | typedef applicative_functor apf_t; 84 | 85 | m_t L1 = {1,2}; 86 | m_t L2 = {'a','b'}; 87 | m_t L3 = {"hello" , "world", "bracketrks"}; 88 | 89 | 90 | auto ff = [] (T1 a, T2 b, T3 c) { return std::make_tuple(a,b,c);}; 91 | 92 | 93 | auto cff = curry(ff); 94 | auto cffl = apf_t::pure(cff); 95 | auto C1 = apf_t::apply(cffl)(L1); 96 | auto C2 = apf_t::apply(C1)(L2); 97 | auto C3 = apf_t::apply(C2)(L3); 98 | 99 | std::cout << C3 << std::endl; 100 | 101 | return 0; 102 | } 103 | 104 | 105 | template using s_t = std::shared_ptr; 106 | 107 | int bracket_4() 108 | { 109 | 110 | typedef int T1; 111 | typedef char T2; 112 | typedef std::string T3; 113 | typedef applicative_functor apf_t; 114 | 115 | s_t L1 = apf_t::pure(1); 116 | s_t L2 = apf_t::pure('a'); 117 | s_t L3 = apf_t::pure(std::string("hello")); 118 | 119 | auto ff = [] (T1 a, T2 b, T3 c) { return std::make_tuple(a,b,c);}; 120 | 121 | auto cff = curry(ff); 122 | auto cffl = apf_t::pure(cff); 123 | auto C1 = apf_t::apply(cffl)(L1); 124 | auto C2 = apf_t::apply(C1)(L2); 125 | auto C3 = apf_t::apply(C2)(L3); 126 | 127 | std::cout << C3 << std::endl; 128 | 129 | return 0; 130 | } 131 | 132 | 133 | int bracket_5 () 134 | { 135 | 136 | std::function(int)> plus = [=] (int x) { 137 | return [=] (int y) { 138 | return x + y; 139 | }; 140 | }; 141 | 142 | std::function(int)> mult = [] (int x) { 143 | return [=] (int y) { 144 | return x * y; 145 | }; 146 | }; 147 | 148 | 149 | typedef applicative_functor apf_t; 150 | 151 | auto pl10 = plus(10); 152 | auto m100 = mult(2); 153 | 154 | auto C1 = functor::fmap(plus,pl10); 155 | auto C2 = apf_t::apply(C1, m100); 156 | 157 | std::cout << " res2 : " << C2(3) << std::endl; 158 | 159 | return 0; 160 | } 161 | 162 | int bracket_6 () 163 | { 164 | 165 | 166 | typedef int T1; 167 | typedef char T2; 168 | typedef std::string T3; 169 | typedef std::string T4; 170 | 171 | m_t L1 = {1,2}; 172 | m_t L2 = {'a','b'}; 173 | m_t L3 = {"hello" , "world", "bracketrks"}; 174 | m_t L4 = {"hhahh" , "no good", "stuff"}; 175 | 176 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 177 | auto f2 = [] (T1 a, T2 b) { return std::make_tuple(a,b);}; 178 | auto f3 = [] (T1 a, T2 b, T3 c) { return std::make_tuple(a,b,c);}; 179 | auto f4 = [] (T1 a, T2 b, T3 c, T4 d) { return std::make_tuple(a,b,c,d);}; 180 | 181 | 182 | 183 | auto R1a = bracket(f1, L1); 184 | std::cout << R1a << std::endl; 185 | 186 | auto cf2 = curry(f2); 187 | auto R2 = bracket_helper<2,std::forward_list, decltype(cf2), T1, T2>::bracket(cf2)(L1)(L2); 188 | std::cout << "R2 :" << R2 << std::endl; 189 | 190 | auto cf3 = curry(f3); 191 | auto R3 = bracket_helper<3,std::forward_list, decltype(cf3), T1, T2, T3>::bracket(cf3)(L1)(L2)(L3); 192 | std::cout << R3 << std::endl; 193 | 194 | //auto cf4 = curry(f4); 195 | //auto R4 = bracket_helper<4,std::forward_list, decltype(cf4), T1, T2, T3, T4>::bracket(cf4)(L1)(L2)(L3)(L4); 196 | auto R4 = bracket(f4, L1, L2,L3,L4); 197 | std::cout << R4 << std::endl; 198 | 199 | return 0; 200 | } 201 | 202 | int bracket_7() 203 | { 204 | typedef int T1; 205 | typedef char T2; 206 | typedef std::string T3; 207 | typedef applicative_functor apf_t; 208 | s_t L1 = apf_t::pure(1); 209 | s_t L2 = apf_t::pure('a'); 210 | s_t L3 = apf_t::pure(std::string("hello")); 211 | 212 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 213 | auto f2 = [] (T1 a, T2 b) { return std::make_tuple(a,b);}; 214 | auto f3 = [] (T1 a, T2 b, T3 c) { return std::make_tuple(a,b,c);}; 215 | 216 | auto R1 = bracket_helper<1, std::shared_ptr, decltype(f1), T1>::bracket(f1)(L1); 217 | std::cout << R1 << std::endl; 218 | 219 | auto cf2 = curry(f2); 220 | auto R2 = bracket_helper<2,std::shared_ptr, decltype(cf2), T1, T2>::bracket(cf2)(L1)(L2); 221 | std::cout << R2 << std::endl; 222 | 223 | auto R3 = bracket(f3, L1, L2,L3); 224 | std::cout << R3 << std::endl; 225 | 226 | return 0; 227 | } 228 | 229 | int bracket_8() 230 | { 231 | typedef int T1; 232 | typedef char T2; 233 | typedef std::string T3; 234 | typedef applicative_functor apf_t; 235 | m_t L1 = {1,2,3}; 236 | m_t L2 = {'y', 'x'}; 237 | m_t L3 = {std::string("hello"), std::string("goodbye")}; 238 | 239 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 240 | auto f2 = [] (T1 a, T2 b) { return std::make_tuple(a,b);}; 241 | auto f3 = [] (T1 a, T2 b, T3 c) { return std::make_tuple(a,b,c);}; 242 | 243 | auto R1 = bracket(f1, L1); 244 | std::cout << R1 << std::endl; 245 | 246 | auto R2 = bracket(f2, L1, L2); 247 | std::cout << R2 << std::endl; 248 | 249 | auto R3 = bracket(f3, L1, L2, L3); 250 | std::cout << R3 << std::endl; 251 | 252 | return 0; 253 | } 254 | 255 | int bracket_9() 256 | { 257 | typedef int T1; 258 | typedef char T2; 259 | forward_list_of_ptr L1 = {std::make_shared(5),std::make_shared(15),std::make_shared(25),std::make_shared(35)}; 260 | forward_list_of_ptr L2 = {std::make_shared('a'),std::make_shared('b'),std::make_shared('c'),std::make_shared('z')}; 261 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 262 | auto R1 = bracket(f1, L1); 263 | std::cout << R1 << std::endl; 264 | 265 | auto f2 = [] (T1 a, T2 b) { return std::make_tuple(a,b);}; 266 | auto R2 = bracket(f2, L1, L2); 267 | std::cout << R2 << std::endl; 268 | 269 | return 0; 270 | } 271 | 272 | int bracket_10() 273 | { 274 | typedef int T1; 275 | forward_zip_list L1 = {1,34,56,78,23,90}; 276 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 277 | auto R1 = bracket(f1, L1); 278 | std::cout << R1 << std::endl; 279 | 280 | auto R2 = bracket(f1, L1); 281 | std::cout <<"no cont explicity specified" << R2 << std::endl; 282 | return 0; 283 | } 284 | 285 | int bracket_11() 286 | { 287 | typedef int T1; 288 | zip_list L1 = {1,34,56,78,23,90}; 289 | auto f1 = [] (T1 a) { return std::make_tuple(a);}; 290 | auto R1 = bracket(f1, L1); 291 | std::cout << R1 << std::endl; 292 | 293 | auto R2 = bracket(f1, L1); 294 | std::cout <<"no cont explicity specified" << R2 << std::endl; 295 | return 0; 296 | } 297 | -------------------------------------------------------------------------------- /src/bracket.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__mbracket__h 2 | #define h__mbracket__h 3 | 4 | #include "bracket_helper.hpp" 5 | 6 | 7 | template class Cont, typename F, typename... T> 8 | auto bracket (F f, Cont... L) 9 | { 10 | auto cf = curry(f); 11 | return bracket_helper::bracket(cf, L...); 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/bracket_helper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__bracket_helper__h 2 | #define h__bracket_helper__h 3 | 4 | 5 | template class Cont, typename F, typename T1, typename T2=T1, typename T3=T2, typename T4=T3> 6 | struct bracket_helper { 7 | 8 | }; 9 | 10 | 11 | template class Cont, typename F, typename T1> 12 | struct bracket_helper<1, Cont, F, T1> { 13 | 14 | static auto bracket(F cf, Cont L1) { 15 | return bracket(cf)(L1); 16 | } 17 | 18 | static auto bracket (F f) { 19 | auto cffl = applicative_functor::pure(f); 20 | return [cffl](Cont L) { 21 | typedef decltype(f(T1())) ret_t; 22 | applicative_functor APF; 23 | auto C = APF.template apply(cffl)(L); 24 | return C; 25 | }; 26 | }; 27 | 28 | }; 29 | 30 | 31 | template class Cont, typename F, typename T1, typename T2> 32 | struct bracket_helper<2, Cont, F, T1, T2> { 33 | static auto bracket(F cf, Cont L1, Cont L2) { 34 | return bracket(cf)(L1)(L2); 35 | } 36 | 37 | static auto bracket(F cf) { 38 | typedef decltype(cf(T1())(T2())) ret_t; 39 | return [cf] (Cont L1) { 40 | auto C = bracket_helper<1, Cont, F, T1>::bracket(cf)(L1); 41 | return [C](Cont L2) { 42 | applicative_functor APF; 43 | auto J = APF.template apply(C)(L2); 44 | return J; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | 51 | template class Cont, typename F, typename T1, typename T2, typename T3> 52 | struct bracket_helper<3, Cont, F, T1, T2, T3> { 53 | 54 | static auto bracket(F cf, Cont L1, Cont L2, Cont L3) { 55 | return bracket(cf)(L1)(L2)(L3); 56 | } 57 | 58 | static auto bracket(F cf) { 59 | typedef decltype(cf(T1())(T2())(T3())) ret_t; 60 | return [cf] (Cont L1) { 61 | auto H = bracket_helper<2, Cont, decltype(cf), T1, T2>::bracket(cf)(L1); 62 | return [H] (Cont L2) { 63 | auto J = H(L2); 64 | return [J](Cont L3) { 65 | applicative_functor APF; 66 | auto K = APF.template apply(J)(L3); 67 | return K; 68 | }; 69 | }; 70 | }; 71 | }; 72 | }; 73 | 74 | template class Cont, typename F, typename T1, typename T2, typename T3, typename T4> 75 | struct bracket_helper<4, Cont, F, T1, T2, T3, T4> { 76 | 77 | static auto bracket(F cf, Cont L1, Cont L2, Cont L3, Cont L4) { 78 | return bracket(cf)(L1)(L2)(L3)(L4); 79 | } 80 | 81 | static auto bracket(F cf) { 82 | typedef decltype(cf(T1())(T2())(T3())(T4())) ret_t; 83 | return [cf] (Cont L1) { 84 | auto H = bracket_helper<3, Cont, decltype(cf), T1, T2,T3>::bracket(cf)(L1); 85 | return [H] (Cont L2) { 86 | auto J1 = H(L2); 87 | return [J1](Cont L3) { 88 | auto J = J1(L3); 89 | return [J] (Cont L4) { 90 | applicative_functor APF; 91 | auto K = APF.template apply(J)(L4); 92 | return K; 93 | }; 94 | }; 95 | }; 96 | }; 97 | }; 98 | }; 99 | 100 | 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/curry.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "curry.hpp" 4 | 5 | 6 | int cur_1() 7 | { 8 | auto plus = [](int x, int y) { return x+y;}; 9 | auto pl = curry(plus); 10 | 11 | std::cout << pl(1)(2) << " , " << plus(1,2) << std::endl; 12 | 13 | auto f = [] (int a, int b, float c, char d, char e) { 14 | return (a+b) * c - ((int) d - (int) e); 15 | }; 16 | auto cf = curry_helper<5, decltype(f), int, int,float,char,char>()(f); 17 | //auto var = cf(f); 18 | std::cout << f(1,2,6.89,'a','z') << "," << cf(1)(2)(6.89)('a')('z') << std::endl; 19 | auto cf2 = curry(f); 20 | std::cout << f(1,2,6.89,'a','z') << "," << cf2(1)(2)(6.89)('a')('z') << std::endl; 21 | 22 | return 0; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/curry.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__curry__h 2 | #define h__curry__h 3 | #include "curry_helper.hpp" 4 | 5 | template 6 | std::function (T)> curry (std::function op) 7 | { 8 | return [op] (T x) { return [op,x] (U y) {return op(x, y);};}; 9 | } 10 | 11 | template 12 | auto curry (F op) 13 | { 14 | return curry_helper()(op); 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/curry_helper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__curry_helper__h 2 | #define h__curry_helper__h 3 | 4 | template 5 | struct curry_helper { 6 | // auto operator()(F op); 7 | 8 | }; 9 | 10 | template 11 | struct curry_helper<1,F,T1> { 12 | auto operator() (F op) { 13 | return [op] (T1 x) {return op(x);}; 14 | } 15 | }; 16 | 17 | template 18 | struct curry_helper<2,F, T1,T2> { 19 | auto operator() (F op) { 20 | return [op] (T1 x) { 21 | return [op,x] (T2 y) { 22 | return op(x,y); 23 | }; 24 | }; 25 | }; 26 | }; 27 | 28 | template 29 | struct curry_helper<3,F,T1,T2,T3> { 30 | auto operator() (F op) { 31 | return [op] (T1 x) { 32 | return [op,x] (T2 y) { 33 | return [op,x,y] (T3 z) { 34 | return op(x,y,z); 35 | }; 36 | }; 37 | }; 38 | }; 39 | }; 40 | 41 | template 42 | struct curry_helper<4,F,T1,T2,T3, T4> { 43 | auto operator() (F op) { 44 | return [op] (T1 x) { 45 | return [op,x] (T2 y) { 46 | return [op,x,y] (T3 z) { 47 | return [op,x,y,z] (T4 w) { 48 | return op(x,y,z,w); 49 | }; 50 | }; 51 | }; 52 | }; 53 | }; 54 | }; 55 | 56 | template 57 | struct curry_helper<5,F,T1,T2,T3, T4, T5> { 58 | auto operator() (F op) { 59 | return [op] (T1 x) { 60 | return [op,x] (T2 y) { 61 | return [op,x,y] (T3 z) { 62 | return [op,x,y,z] (T4 w) { 63 | return [op,x,y,z,w] (T5 p) { 64 | return op(x,y,z,w,p); 65 | }; 66 | }; 67 | }; 68 | }; 69 | }; 70 | }; 71 | }; 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/either.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "either.hpp" 4 | 5 | 6 | /////////////////////////////////////////////////////// 7 | 8 | int ei_0() 9 | { 10 | 11 | auto val = Either::Left("hello"); 12 | std::cerr << val << std::endl; 13 | 14 | auto v2 = Either::Right("hello"); 15 | std::cerr << v2 << std::endl; 16 | 17 | auto v3 = v2; 18 | std::cerr << v3 << std::endl; 19 | 20 | return 0; 21 | } 22 | 23 | int ei_1() 24 | { 25 | auto v = Either::Right(45); 26 | std::cerr << v << "=>" << Left(v) << ":" << Right(v) << std::endl; 27 | return 0; 28 | } 29 | 30 | int ei_2() 31 | { 32 | 33 | auto v1 = Either::Right(45); 34 | auto v2 = Either::Right(46); 35 | auto v3 = Either::Right('x'); 36 | if (v1 == v1) { 37 | std::cerr << "v1==v1 : " << v1 << std::endl; 38 | } 39 | 40 | if (v1 == v2) { 41 | std::cerr << "v1==v2: " << v1 << " : " << v2 << std::endl; 42 | } 43 | 44 | if (v1 != v2) { 45 | std::cerr << "v1!=v2: " << v1 << " : " << v2 << std::endl; 46 | } 47 | 48 | if (v1 == v3) { 49 | std::cerr << "v1==v3: " << v1 << " : " << v3 << std::endl; 50 | } 51 | 52 | if (v1 != v3) { 53 | std::cerr << "v1!=v3: " << v1 << " : " << v3 << std::endl; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | int ei_3() 60 | { 61 | 62 | auto f = [](int x){return 2+x;}; 63 | auto val = Either::Left(f); 64 | std::cerr << val.left()(23) << std::endl; 65 | 66 | auto v2 = Either::Right(f); 67 | std::cerr << v2.right()(23) << std::endl; 68 | 69 | return 0; 70 | } 71 | 72 | int ei_4() 73 | { 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /src/either.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__either__h 2 | #define h__either__h 3 | #include "maybe.hpp" 4 | 5 | 6 | template 7 | struct Either { 8 | 9 | typedef L left_value_type; 10 | typedef R right_value_type; 11 | 12 | Either(const Either& o) : value(o.value) {} 13 | 14 | void operator=(const Either&) = delete; 15 | 16 | static Either Left(const L& l) { 17 | return Either(l, true); 18 | } 19 | 20 | static Either Right(const R& r) { 21 | return Either(r); 22 | } 23 | 24 | bool Left() const { 25 | return std::get<2>(value); 26 | } 27 | 28 | bool Right() const { 29 | return (! Left()); 30 | } 31 | 32 | std::ostream& pp(std::ostream& strm) const { 33 | strm << "Either<" << typeid(L).name() << "," << typeid(R).name() << ">";; 34 | if (std::get<2>(value)) { 35 | strm << "[" << left() << ", null]"; 36 | } 37 | else { 38 | strm << "[null," << right() << "]"; 39 | } 40 | return strm; 41 | } 42 | 43 | bool eq(const Either& o) const { 44 | auto eqval = [this] (const value_t& l, const value_t& r) { 45 | if (std::get<2>(value)) return std::get<0>(l) == std::get<0>(r); 46 | return std::get<1>(l) == std::get<1>(r); 47 | }; 48 | return ((std::get<2>(value) == std::get<2>(o.value)) 49 | && eqval(value, o.value)); 50 | } 51 | 52 | const L& left() const { 53 | return std::get<0>(value); 54 | } 55 | 56 | const R& right() const { 57 | return std::get<1>(value); 58 | } 59 | 60 | private : 61 | Either (L val, bool left) : value(std::make_tuple(val,R(),true)) {} 62 | Either (R val) : value(std::make_tuple(L(), val,false)) {} 63 | 64 | typedef std::tuple value_t; 65 | value_t value; 66 | 67 | }; 68 | 69 | 70 | template 71 | std::ostream& operator<<(std::ostream& strm, const Either& E) 72 | { 73 | E.pp(strm); 74 | return strm; 75 | } 76 | 77 | 78 | template 79 | Maybe Left(const Either& e) 80 | { 81 | if (e.Left()) { 82 | return just(e.left()); 83 | } 84 | return none(); 85 | } 86 | 87 | template 88 | Maybe Right(const Either& e) 89 | { 90 | if (e.Right()) { 91 | return just(e.right()); 92 | } 93 | return none(); 94 | } 95 | 96 | template 97 | bool operator==(const Either& a, const Either& b) { 98 | return false; 99 | } 100 | 101 | template 102 | bool operator==(const Either& a, const Either& b) { 103 | return a.eq(b); 104 | } 105 | 106 | template 107 | bool operator!=(const Either& a, const Either& b) { 108 | return !(a==b); 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /src/either_monad.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "either_monad.hpp" 4 | #include "curry.hpp" 5 | #include "bracket.hpp" 6 | 7 | ////////////////////////////////////////////////////// 8 | int eim_0() 9 | { 10 | auto v1 = Either::Right(45); 11 | auto v2 = Either::Left("a value"); 12 | auto l = [](int x) { 13 | return 2+x; 14 | }; 15 | std::cerr << v1 << " --> " << functor::fmap(l, v1) << std::endl; 16 | std::cerr << v2 << " --> " << functor::fmap(l, v2) << std::endl; 17 | return 0; 18 | } 19 | 20 | int eim_1() 21 | { 22 | auto v1 = Either::Right(45); 23 | auto v2 = Either::Left("a value"); 24 | 25 | auto l = [](int x) { 26 | return 2+x*3; 27 | }; 28 | 29 | auto ll = applicative_functor::pure(l); 30 | std::cerr << v1 << " --> " << applicative_functor::apply(ll, v1) << std::endl; 31 | std::cerr << v2 << " --> " << functor::fmap(l, v2) << std::endl; 32 | 33 | return 0; 34 | } 35 | 36 | int eim_2() 37 | { 38 | std::function< Either (int)> f = [](int x) { 39 | if (x < 0) { 40 | return Either::Left(std::string("smaller than 0")); 41 | } 42 | return Either::Right(1.15*x-10);; 43 | }; 44 | 45 | std::function< Either (int, Either)> repeat = [&](int n, Either e) { 46 | if ( n == 0) return e; 47 | std::cerr << n << " : " << e << std:: endl << " -> "; 48 | return repeat(n-1, monad::bind(e,f)); 49 | }; 50 | auto v = repeat(12, Either::Right(45)); 51 | std::cerr << v << std::endl; 52 | return 0; 53 | } 54 | 55 | int eim_3() 56 | { 57 | std::function< Either (int)> f = [](int x) { 58 | if (x < 0) { 59 | return Either::Left(std::string("smaller than 0")); 60 | } 61 | return Either::Right(1.15*x-10);; 62 | }; 63 | auto e = Either::Right(-45); 64 | auto r = monad::bind(e)(f); 65 | std::cerr << e << " -> " << r << std::endl; 66 | return 0; 67 | } 68 | 69 | 70 | int eim_4() 71 | { 72 | auto f = std::plus(); 73 | 74 | std::function (int)> cf = curry(f); 75 | std::cerr << " 23 + 45 = " << f(23,45) << std::endl; 76 | std::cerr << " 23 + 45 = " << cf(23)(45) << std::endl; 77 | 78 | auto F = applicative_functor::pure(cf); 79 | auto V1 = applicative_functor::pure(23); 80 | auto V2 = applicative_functor::pure(45); 81 | std::cerr << V1 << " " << V2 << std::endl; 82 | 83 | auto A1 = applicative_functor::apply(F, V1); 84 | auto A2 = applicative_functor::apply(A1, V2); 85 | std::cerr << A2 << std::endl; 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/either_monad.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__either_monad__h 2 | #define h__either_monad__h 3 | #include "either.hpp" 4 | #include "functor.hpp" 5 | #include "applicative_functor.hpp" 6 | #include "monad.hpp" 7 | 8 | template <> 9 | struct functor { 10 | 11 | //curried version 12 | template 13 | static auto fmap(lambda f) -> std::function < Either (Either)> { 14 | return [&f](Either e) { 15 | return fmap(f, e); 16 | }; 17 | } 18 | 19 | // uncurried, for functions.. 20 | 21 | template 22 | static auto fmap(lambda f, Either e) -> Either { 23 | if (e.Left()) { 24 | return Either::Left(e.left()); 25 | } 26 | return Either::Right(f(e.right())); 27 | }; 28 | }; 29 | 30 | template <> 31 | struct applicative_functor : public functor 32 | { 33 | 34 | template 35 | static Either pure(A val) { 36 | return Either::Right(val); 37 | } 38 | 39 | template 40 | static auto apply(Either F , Either m) { 41 | return functor::fmap(F.right(), m); 42 | }; 43 | 44 | template 45 | static auto apply(Either F) { 46 | return [F] (Either m) { 47 | return apply(F,m); 48 | }; 49 | }; 50 | 51 | }; 52 | 53 | template <> 54 | struct monad : public applicative_functor 55 | { 56 | template 57 | static Either mreturn (A val) { 58 | return applicative_functor::pure(val); 59 | } 60 | 61 | template 62 | static auto bind(Either e) { 63 | return [e](lambda F) { 64 | return bind(e, F); 65 | }; 66 | } 67 | 68 | template 69 | static auto bind(Either e, lambda F) { 70 | if (e.Left()) { 71 | return Either::Left(e.left()); 72 | } 73 | return F(e.right()); 74 | } 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/fold.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __fold__ 2 | #define __fold__ 3 | template 4 | U foldl(std::function< U (U, T)>& op, const U& val, const std::forward_list& L) 5 | { 6 | U acc(val); 7 | for (auto &v : L) { 8 | acc = op(acc, v); 9 | } 10 | return acc; 11 | } 12 | 13 | 14 | template 15 | U foldl(std::function< U (U, T)>& op, const std::forward_list& L) 16 | { 17 | U acc = U(); 18 | for (auto &v : L) { 19 | acc = op(acc, v); 20 | } 21 | return acc; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/forward_zip_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__forwardziplist__h 2 | #define h__forwardziplist__h 3 | 4 | template using forward_zip_list = std::forward_list; 5 | 6 | template <> 7 | struct functor { 8 | 9 | template 10 | static std::function (forward_zip_list)> fmap (std::function f) { 11 | return [f](forward_zip_list L) { 12 | return functor::fmap(f, L); 13 | }; 14 | } 15 | 16 | 17 | template 18 | static std::function (forward_zip_list)> fmap (F f) { 19 | return [f](forward_zip_list L) { 20 | return functor::fmap(f, L); 21 | }; 22 | }; 23 | 24 | }; 25 | 26 | template<> struct 27 | applicative_functor :public functor{ 28 | 29 | template 30 | static forward_zip_list pure(A v) { 31 | return applicative_functor::pure(v); 32 | } 33 | 34 | template 35 | static std::function< forward_zip_list (forward_zip_list)> apply(forward_zip_list> F) { 36 | return [F](forward_zip_list L) { 37 | forward_zip_list acc; 38 | auto it1 = F.begin(); 39 | auto it2 = L.begin(); 40 | while (it1 != F.end() && it2 != L.end()) { 41 | auto func = *it1; 42 | auto arg = *it2; 43 | acc.push_front(func(arg)); 44 | it1++; 45 | it2++; 46 | } 47 | acc.reverse(); 48 | return acc; 49 | }; 50 | }; 51 | 52 | template 53 | static std::function< forward_zip_list (forward_zip_list)> apply(forward_zip_list F) { 54 | return [F](forward_zip_list L) { 55 | forward_zip_list acc; 56 | auto it1 = F.begin(); 57 | auto it2 = L.begin(); 58 | while (it1 != F.end() && it2 != L.end()) { 59 | auto func = *it1; 60 | auto arg = *it2; 61 | acc.push_front(func(arg)); 62 | it1++; 63 | it2++; 64 | } 65 | acc.reverse(); 66 | return acc; 67 | }; 68 | }; 69 | 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/functor.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "w.hpp" 4 | #include "map.hpp" 5 | #include "functor.hpp" 6 | #include "applicative_functor.hpp" 7 | 8 | 9 | int functor_1() 10 | { 11 | std::forward_list L = {W(10, "a"), W(20, "b"), W(3467, "mnhjk")}; 12 | std::function show =[](W w) { w.pp(std::cerr) << std::endl; return w.ssn();}; 13 | functor::fmap(show)(L); 14 | 15 | return 0; 16 | } 17 | 18 | int functor_2() 19 | { 20 | std::function f = [=](int x) { return 3 * x;}; 21 | std::function g = [=](int x) { return 100 + x;}; 22 | auto res = functor::fmap(f,g); 23 | std::cout << " res : " << res(1) << std::endl; 24 | auto res1 = functor::fmap(f)(g); 25 | std::cout << " res : " << res1(1) << std::endl; 26 | return 0; 27 | } 28 | 29 | int functor_3() 30 | { 31 | std::function f = [](int x) { return 3 * x;}; 32 | std::function g = [](int x) { return 100 + x;}; 33 | std::function h = [](int x) { return 5 * x - 700;}; 34 | auto r = functor::fmap(f,g); 35 | auto res = functor::fmap(h, r); 36 | std::cout << " res : " << res(1) << std::endl; 37 | return 0; 38 | } 39 | 40 | int functor_4() 41 | { 42 | std::function f = [](int x) { return 3 * x;}; 43 | std::function g = [](int x) { return 100 + x;}; 44 | auto res = functor::fmap(f)(g); 45 | 46 | std::cout << " res : " << res(1) << std::endl; 47 | return 0; 48 | } 49 | 50 | int functor_5() 51 | { 52 | std::forward_list L = {W(10, "a"), W(20, "b"), W(3467, "mnhjk")}; 53 | std::function show =[](W w) { w.pp(std::cerr) << std::endl; return w.ssn();}; 54 | functor::fmap(show, L); 55 | 56 | return 0; 57 | } 58 | 59 | int functor_6() 60 | { 61 | std::function(int)> plus = [] (int x) { 62 | return [=] (int y) { 63 | return x + y; 64 | }; 65 | }; 66 | 67 | auto pl3 = plus (3); 68 | 69 | std::cout << " 3 + 9 : " << pl3(9) << std::endl; 70 | 71 | auto r = functor::fmap(plus,pl3); 72 | int v = r(0)(0) ; 73 | std::cout << " r (5) : " << v << std::endl; 74 | return 0; 75 | } 76 | 77 | 78 | int functor_7() 79 | { 80 | std::list L = {W(10, "a"), W(20, "b"), W(3467, "mnhjk")}; 81 | std::function show =[](W w) { w.pp(std::cerr) << std::endl; return w.ssn();}; 82 | functor::fmap(show)(L); 83 | 84 | return 0; 85 | } 86 | 87 | int functor_8() 88 | { 89 | std::list> L = {std::shared_ptr{new W(10, "a")}, std::shared_ptr{new W(20, "b")}, std::shared_ptr{new W(3467, "mnhjk")}}; 90 | auto F = functor::fmap(std::function([](const W& w) { w.pp(std::cerr) << std::endl; return w;})); 91 | functor::fmap(F, L); 92 | return 0; 93 | } 94 | 95 | int functor_9() 96 | { 97 | typedef std::tuple C; 98 | std::list> L = {std::shared_ptr{new C(10, "a")}, std::shared_ptr{new C(20, "b")}, std::shared_ptr{new C(3467, "mnhjk")}}; 99 | auto F = functor::fmap(std::function([](const C& c) { std::cerr << c << std::endl; return c;})); 100 | functor::fmap(F, L); 101 | return 0; 102 | } 103 | 104 | int functor_10() 105 | { 106 | std::function f = [](int x) {return 2*x + 89;}; 107 | int *p = new int(78); 108 | int *t = functor::fmap(f)(p); 109 | std::cerr << " *p " << *p << " ==> " << *t << std::endl; 110 | return 0; 111 | } 112 | 113 | int functor_11() 114 | { 115 | return 0; 116 | } 117 | 118 | 119 | int functor_12() 120 | { 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /src/functor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef H__FUNCTOR__H 2 | #define H__FUNCTOR__H 3 | 4 | template class F> 5 | struct functor { 6 | 7 | //curried version 8 | template 9 | static std::function < F (F)> fmap(std::function f); 10 | 11 | // uncurried, for functions.. 12 | template 13 | static F fmap(std::function f, F L) { 14 | return fmap(f)(L); 15 | } 16 | }; 17 | 18 | //----------------------------- Implementation ----------------------- 19 | #include "map.hpp" 20 | #include "unary_op.hpp" 21 | #include "raw_pointer.hpp" 22 | 23 | template <> 24 | struct functor { 25 | 26 | template 27 | static std::function (std::shared_ptr)> fmap (std::function f) { 28 | return [f](std::shared_ptr v) { 29 | if (v) { 30 | return std::make_shared(f(*v)); 31 | } 32 | return std::shared_ptr(nullptr); 33 | }; 34 | } 35 | 36 | template 37 | static std::function (std::shared_ptr)> fmap (F f) { 38 | return [f](std::shared_ptr v) { 39 | if (v) { 40 | return std::make_shared(f(*v)); 41 | } 42 | return std::shared_ptr(nullptr); 43 | }; 44 | } 45 | }; 46 | 47 | template<> struct 48 | functor { 49 | template 50 | static std::function < std::forward_list (std::forward_list)> fmap(std::function f) { 51 | return [f] (std::forward_list L) { 52 | return map(f,L); 53 | }; 54 | }; 55 | 56 | template 57 | static std::forward_list fmap(std::function f, std::forward_list L) { 58 | return fmap(f)(L); 59 | }; 60 | 61 | template 62 | static std::forward_list fmap(F f, std::forward_list L) { 63 | return map(f, L); 64 | }; 65 | 66 | }; 67 | 68 | 69 | template<> struct 70 | functor { 71 | 72 | template 73 | static std::function < std::list (std::list)> fmap(std::function f) { 74 | return [f] (std::list L) { 75 | return map(f,L); 76 | }; 77 | }; 78 | 79 | template 80 | static std::list fmap(std::function f, std::list L) { 81 | return fmap(f)(L); 82 | }; 83 | 84 | template 85 | static auto fmap(F f, std::list L) -> std::list { 86 | return map(f, L); 87 | }; 88 | template 89 | static auto fmap(F f, std::list L) -> std::list { 90 | return map(f, L); 91 | }; 92 | 93 | }; 94 | 95 | 96 | template<> 97 | struct functor 98 | { 99 | 100 | template 101 | static auto fmap (std::function f) { 102 | return [f](std::function g) { 103 | return [f,g] (R x) { 104 | return f(g(x)); 105 | }; 106 | }; 107 | }; 108 | 109 | template 110 | static std::function fmap (std::function f, std::function g) { 111 | return [f,g](R x) -> B { 112 | return f(g(x)); 113 | }; 114 | }; 115 | 116 | }; 117 | 118 | template <> 119 | struct functor { 120 | 121 | template 122 | static std::function fmap (std::function f) { 123 | return [f](A* v) { 124 | if (v) { 125 | return new B(f(*v)); 126 | } 127 | return static_cast(nullptr); 128 | }; 129 | } 130 | 131 | template 132 | static std::function fmap (F f) { 133 | return [f](A* v) { 134 | if (v) { 135 | return new B(f(*v)); 136 | } 137 | return static_cast(nullptr); 138 | }; 139 | } 140 | }; 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /src/future_value.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "future_value.hpp" 4 | 5 | #include 6 | 7 | ///////////////////////////////////////////////////////////////////////////// 8 | int fv_0() 9 | { 10 | std::function f = [](int x) { 11 | std::cerr << "start..." << std::endl; 12 | int n = 5; 13 | while (n--) { 14 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 15 | std::cerr << "."; 16 | } 17 | std::cerr << std::endl; 18 | return x+45; 19 | }; 20 | future_value fv(f); 21 | std::cerr << fv << std::endl; 22 | auto res = runFutureValue(fv, 45); 23 | std::cerr << res << std::endl; 24 | 25 | return 0; 26 | } 27 | 28 | int fv_1() 29 | { 30 | std::function f = [](int x) { 31 | std::cerr << "start..." << std::endl; 32 | int n = 5; 33 | while (n--) { 34 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 35 | std::cerr << "."; 36 | } 37 | std::cerr << std::endl; 38 | return x+45; 39 | }; 40 | std::function g = [](int x) { 41 | std::cerr << "start+++" << std::endl; 42 | int n = 5; 43 | while (n--) { 44 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 45 | std::cerr << "?"; 46 | } 47 | std::cerr << std::endl; 48 | return x+56; 49 | }; 50 | 51 | future_value fv = make_future_value(g) + make_future_value(f); 52 | 53 | std::cerr << fv << std::endl; 54 | auto res = runFutureValue(fv, 45); 55 | std::cerr << res << std::endl; 56 | return 0; 57 | 58 | 59 | } 60 | 61 | int fv_2() 62 | { 63 | std::function f = [](int x, int y, float z) { return z *(34*x - x*y);}; 64 | auto fv = make_future_value(f); 65 | std::cerr << fv << std::endl; 66 | auto res = runFutureValue(fv, 1,2,0.45677); 67 | std::cerr << res << std::endl; 68 | return 1; 69 | } 70 | 71 | int fv_3() 72 | { 73 | std::function f = [](int x, int y, float z) { return z *(34*x - x*y);}; 74 | return 1; 75 | } 76 | 77 | int fv_4() 78 | { 79 | return 1; 80 | } 81 | 82 | int fv_5() 83 | { 84 | return 1; 85 | } 86 | -------------------------------------------------------------------------------- /src/future_value.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__future_value__h 2 | #define h__future_value__h 3 | #include 4 | #include 5 | #include 6 | #include "maybe.hpp" 7 | #include "thunk.hpp" 8 | 9 | 10 | template 11 | struct future_value { 12 | explicit future_value(std::function f) : F(f){} 13 | future_value(const future_value& o) : F(o.F) {} 14 | const future_value operator=(const future_value& o) { 15 | if (o == &this) return *this; 16 | F = o.F; 17 | return *this; 18 | } 19 | 20 | std::ostream& pp(std::ostream& strm) const { 21 | strm << "future_value <" ; 22 | strm << typeid(Ret).name() << "," ; 23 | typeids(strm); 24 | if (F != nullptr) { 25 | strm << "> (" << F << ")"; 26 | } 27 | return strm; 28 | } 29 | 30 | Maybe operator()(Arg... args) { 31 | try { 32 | auto th = thunk(F, args...); 33 | auto f = std::async([&th]{return th();}); 34 | return just(f.get()); 35 | } catch (const std::exception& e) { 36 | std::cerr << "exception : " << e.what() << std::endl; 37 | } 38 | return none(); 39 | } 40 | 41 | std::function operator*() const { 42 | return F; 43 | } 44 | 45 | private : 46 | std::function F; 47 | }; 48 | 49 | template 50 | std::ostream& operator<<(std::ostream& strm, const future_value& fv) 51 | { 52 | return fv.pp(strm);; 53 | } 54 | 55 | 56 | template 57 | Maybe runFutureValue(future_value fv, Arg... arg) 58 | { 59 | return fv(arg...); 60 | } 61 | 62 | template 63 | future_value operator+(future_value l, future_value r) 64 | { 65 | std::function F = [l, r] (A val) { 66 | return (*l)((*r)(val)); 67 | }; 68 | 69 | return future_value(F); 70 | } 71 | 72 | template 73 | future_value make_future_value(std::function F) 74 | { 75 | return future_value(F); 76 | } 77 | 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/future_value_monad.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "future_value_monad.hpp" 4 | #include "curry.hpp" 5 | #include "bracket.hpp" 6 | 7 | ////////////////////////////////////////////////////////// 8 | int fvm_0() 9 | { 10 | 11 | std::function f = [](int x) { 12 | std::cerr << "start..." << std::endl; 13 | int n = 5; 14 | while (n--) { 15 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 16 | std::cerr << "."; 17 | } 18 | std::cerr << std::endl; 19 | return x+45; 20 | }; 21 | 22 | std::function g = [](int x) { 23 | std::cerr << "start+++" << std::endl; 24 | int n = 5; 25 | while (n--) { 26 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 27 | std::cerr << "?"; 28 | } 29 | std::cerr << std::endl; 30 | return x+56; 31 | }; 32 | 33 | future_value fv = functor::fmap(g, make_future_value(f)); 34 | 35 | std::cerr << fv << std::endl; 36 | 37 | auto r0 = runFutureValue(fv, 45); 38 | std::cerr << r0 << std::endl; 39 | auto r1 = runFutureValue(fv, -23); 40 | std::cerr << r1 << std::endl; 41 | 42 | return 0; 43 | } 44 | 45 | int fvm_1() 46 | { 47 | 48 | std::function f = [](int x) { 49 | std::cerr << "start..." << std::endl; 50 | int n = 5; 51 | while (n--) { 52 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 53 | std::cerr << "."; 54 | } 55 | std::cerr << std::endl; 56 | return x+45; 57 | }; 58 | 59 | std::function g = [](int x) { 60 | std::cerr << "start+++" << std::endl; 61 | int n = 5; 62 | while (n--) { 63 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 64 | std::cerr << "?"; 65 | } 66 | std::cerr << std::endl; 67 | return x+56; 68 | }; 69 | 70 | std::function (int, future_value)> repeat = [&repeat,f,g] (int count, future_value fv) { 71 | if (count < 1) return fv; 72 | future_value fv1 = functor::fmap(g, fv); 73 | future_value fv2 = functor::fmap(g, fv1); 74 | future_value fv3 = functor::fmap(f, fv2); 75 | return repeat(count-1, fv3); 76 | }; 77 | 78 | future_value fv0 = functor::fmap(g, make_future_value(f)); 79 | future_value fv1 = repeat(10, fv0); 80 | 81 | auto r0 = runFutureValue(fv1, 45); 82 | std::cerr << r0 << std::endl; 83 | 84 | return 0; 85 | } 86 | 87 | int fvm_2() 88 | { 89 | 90 | auto fv = applicative_functor::pure(4500); 91 | 92 | auto r0 = runFutureValue(fv, 45); 93 | std::cerr << r0 << std::endl; 94 | 95 | std::function func =[](int x) { return 5*x + 34;}; 96 | 97 | auto fw = applicative_functor::pure(func); 98 | 99 | auto r1 = runFutureValue(fw, 45); 100 | 101 | std::cerr << r1 << " ----> " << (*r1)(70) << std::endl; 102 | 103 | return 0; 104 | } 105 | 106 | int fvm_3() 107 | { 108 | 109 | std::function func1 =[](int x) { return 5*x + 34;}; 110 | std::function func2 =[](int x) { return 5-x;}; 111 | 112 | future_value, int> fw = applicative_functor::pure(func1); 113 | std::cerr << " fw : " << fw << std::endl; 114 | 115 | auto ty = runFutureValue(fw, 67); 116 | std::cerr << " ty : " << ty << " -- (*ty)(45) : " << (*ty)(45) << std::endl; 117 | 118 | future_value fvv(func2); 119 | std::cerr << "fvv : " << fvv << std::endl; 120 | 121 | auto r1 = runFutureValue(fvv, 45); 122 | std::cerr << " r1 : " << r1 << std::endl; 123 | 124 | auto fv = applicative_functor::apply(fw, fvv); 125 | auto r0 = runFutureValue(fv, 45); 126 | std::cerr << "r0 : " << r0 << std::endl; 127 | 128 | auto fv1 = applicative_functor::apply(fw)(fvv); 129 | auto r01 = runFutureValue(fv, 45); 130 | std::cerr << r01 << std::endl; 131 | 132 | future_value fv0 = functor::fmap(func1, fvv); 133 | auto r02 = runFutureValue(fv0, 45); 134 | std::cerr << "r02 : " << r02 << std::endl; 135 | 136 | return 0; 137 | } 138 | 139 | int fvm_4() 140 | { 141 | std::function func1 =[](int x) { return 5*x + 34;}; 142 | 143 | std::function(int)> func2 = [] (int x) { 144 | std::function f =[] (int x) { 145 | if (x < 100) return std::string("too small"); 146 | return std::string("just right"); 147 | }; 148 | return make_future_value(f); 149 | }; 150 | 151 | auto fv = make_future_value(func1); 152 | std::cerr << fv << std::endl; 153 | std::cerr << func2 << std::endl; 154 | auto res = runFutureValue(fv, 45); 155 | std::cerr << res << std::endl; 156 | std::cerr << "------------------- ****** -----------------------------" << std::endl; 157 | auto fy = monad::bind(fv, func2); 158 | auto mres = runFutureValue(fy, -90); 159 | std::cerr << mres << std::endl; 160 | return 0; 161 | } 162 | 163 | int fvm_5() 164 | { 165 | 166 | std::function func1 =[](int x) { return 5*x + 34;}; 167 | 168 | std::function(int)> func2 = [] (int x) { 169 | 170 | std::function f =[] (int x) { 171 | return -30*x + 90; 172 | }; 173 | 174 | std::function g =[] (int x) { 175 | return 90 - 900*x; 176 | }; 177 | 178 | if (x < 100) { 179 | return make_future_value(f); 180 | } 181 | return make_future_value(g); 182 | }; 183 | 184 | auto fv = make_future_value(func1); 185 | auto fy = monad::bind(fv, func2); 186 | auto mres = runFutureValue(fy, -90); 187 | std::cerr << "-90 ==> " << mres << std::endl; 188 | auto mres1 = runFutureValue(fy, 90); 189 | std::cerr << "90 ==> " << mres1 << std::endl; 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /src/future_value_monad.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__future_value_monad__h 2 | #define h__future_value_monad__h 3 | 4 | #include "future_value.hpp" 5 | #include "functor.hpp" 6 | #include "applicative_functor.hpp" 7 | #include "monad.hpp" 8 | #include "maybe.hpp" 9 | 10 | template<> 11 | struct functor { 12 | 13 | //curried version 14 | template 15 | static auto fmap(lambda f) { // -> std::function < FutureValue (future_value)> { 16 | return [&f](future_value e) { 17 | return fmap(f, e); 18 | }; 19 | } 20 | 21 | // uncurried, for functions.. 22 | 23 | template 24 | static auto fmap(lambda f, future_value e) -> future_value { 25 | return make_future_value(f) + e; 26 | }; 27 | }; 28 | 29 | 30 | template <> 31 | struct applicative_functor : public functor 32 | { 33 | 34 | template 35 | static future_value pure(Ret val) { 36 | std::function F = [val] (Arg arg) { 37 | return val; 38 | }; 39 | return make_future_value(F); 40 | } 41 | 42 | template 43 | static future_value apply(const future_value,A>& F, const future_value& L) { 44 | std::function Func = [F,L] (A x) { 45 | // this can be run in parallel.. 46 | auto val = runFutureValue(L, x); 47 | auto rev = runFutureValue(F, x); 48 | if (val == NONE || rev.none()) { 49 | return R(); 50 | } 51 | return (*rev)(*val); 52 | }; 53 | return make_future_value(Func); 54 | }; 55 | 56 | 57 | template 58 | static auto apply(const future_value,A>& F) { 59 | return [F] (const future_value& L) { 60 | return apply(F,L); 61 | }; 62 | }; 63 | 64 | 65 | }; 66 | 67 | template<> 68 | struct monad : public applicative_functor 69 | { 70 | template 71 | static future_value mreturn(Ret val) { 72 | return pure(val); 73 | }; 74 | 75 | template 76 | static future_value bind(future_value& F, std::function< future_value (Ret)>& f) { 77 | 78 | std::function comp =[&F, &f](Arg x) { 79 | auto val = runFutureValue(F, x); 80 | if (val == NONE) { 81 | return RetB(); 82 | } 83 | 84 | auto cal = runFutureValue(f(*val), *val); 85 | if (cal == NONE) { 86 | return RetB(); 87 | } 88 | return *cal; 89 | }; 90 | 91 | return make_future_value(comp); 92 | }; 93 | 94 | 95 | }; 96 | 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/lambda.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "curry.hpp" 3 | 4 | int lambda_1() 5 | { 6 | int x = 0; 7 | int y = 42; 8 | std::cerr << "hello world" << std::endl; 9 | auto func = [x, &y] () { std::cout << "Hello world from lambda : " << x << "," << y << std::endl; }; 10 | auto inc = [&y] () { y++; }; 11 | auto inc_alt = [y] () mutable { y++; }; 12 | auto inc_alt_alt = [&] () { y++; x++; }; 13 | func(); 14 | 15 | y = 900; 16 | func(); 17 | inc(); 18 | func(); 19 | inc_alt(); 20 | func(); 21 | inc_alt_alt(); 22 | func();//notice what gets outputted here ! 23 | std::cout << " x :" << x << "; y :" << y << std::endl; 24 | return 0; 25 | 26 | } 27 | 28 | int lambda_2() 29 | { 30 | 31 | auto f = [] (int x) { return [=] (int y) {return x + y;};}; 32 | std::cout << f(2)(3) << std::endl; 33 | return 0; 34 | } 35 | 36 | // (x,y) => (x)->(y) 37 | int lambda_3() 38 | { 39 | std::function op = [] (int x, int y) { return x * y;}; 40 | std::cout << op(5,2) << std::endl; 41 | auto f = [=] (int x) { return [=] (int y) {return op(x, y);};}; 42 | std::cout << f(5)(2) << std::endl; 43 | 44 | return 0; 45 | 46 | } 47 | 48 | 49 | int lambda_4() 50 | { 51 | std::function op = [] (int x, int y) { return x * y;}; 52 | std::function (int)>l = [=] (int x) { return [=] (int y) {return op(x, y);};}; 53 | std::cout << l(8)(9) << std::endl; 54 | return 0; 55 | 56 | } 57 | 58 | std::function (int)> cy (std::function op) 59 | { 60 | return [=] (int x) { return [=] (int y) {return op(x, y);};}; 61 | } 62 | 63 | int lambda_5 () 64 | { 65 | auto l = cy ([](int x, int y) { return x * y;}); 66 | std::cout << l(8)(9) << std::endl; 67 | return 0; 68 | 69 | } 70 | 71 | 72 | int lambda_6 () 73 | { 74 | auto l = curry ([](int x, int y) { return (5 + x) * y;}); 75 | std::cout << l(1)(1) << std::endl; 76 | return 0; 77 | } 78 | 79 | int lambda_7 () 80 | { 81 | // as opposed to [=] or [] or [l] 82 | std::function factorial = [&factorial] (int x) ->int { 83 | std::cout << x << ","; 84 | if (x == 0) return 1; 85 | return x * factorial(x-1); 86 | 87 | }; 88 | auto res = factorial(10); 89 | std::cout << std::endl; 90 | std::cout << "res : " << res << std::endl; 91 | return 0; 92 | } 93 | 94 | int lambda_8() 95 | { 96 | auto l1 = [] (int x) { 97 | return 5*x; 98 | }; 99 | 100 | auto l2 = [] (decltype(l1) f, int x) { 101 | return f(x); 102 | }; 103 | 104 | std::cout << l2(l1, 67) << std::endl; 105 | 106 | return 0; 107 | } 108 | 109 | //p f g x = f x (g x) 110 | //p (\x-> (\y-> x + y-90)) (\x-> 2 * x) 6 111 | //Prelude> :t p2 112 | //p2 :: (t2 -> t1 -> t) -> (t2 -> t1) -> t2 -> t 113 | 114 | template 115 | C p2 (std::function f, std::function g, const A& x) 116 | { 117 | return f(x, g(x)); 118 | } 119 | 120 | template 121 | std::function p22 (std::function f, std::function g) 122 | { 123 | return [&](A x) { return f(x, g(x)); }; 124 | } 125 | 126 | template 127 | std::function (std::function) > p2233 (std::function f) 128 | { 129 | return [=](std::function g)->std::function {return [=](A x)->C { return f(x, g(x)); }; }; 130 | } 131 | 132 | int lambda_9() 133 | { 134 | std::function f = [](int x, int y) {return x + y - 90;}; 135 | std::function g = [](int x) {return 2 * x ;}; 136 | auto val = p2(f, g, 6); 137 | std::cout << "val : " << val << std::endl; 138 | 139 | auto F = p22 (f, g); 140 | auto val2 = F(6); 141 | std::cout << "val1 : " << val << " "; 142 | std::cout << "val2 : " << val2 << " "; 143 | std::cout << "val3 : " << p2233(f)(g)(6) << " "; 144 | std::cout << std::endl; 145 | return 1; 146 | } 147 | -------------------------------------------------------------------------------- /src/list_of_ptr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__list_of_ptr__h 2 | #define h__list_of_ptr__h 3 | 4 | /* 5 | implementation of functors and applicative functors for a list of pointers 6 | */ 7 | template using forward_list_of_ptr = std::forward_list>; 8 | 9 | 10 | template <> 11 | struct functor { 12 | 13 | template 14 | static std::function (forward_list_of_ptr)> fmap (std::function f) { 15 | auto F = functor::fmap(f); 16 | return [F](forward_list_of_ptr L) { 17 | return functor::fmap(F, L); 18 | }; 19 | } 20 | 21 | template 22 | static std::function (forward_list_of_ptr)> fmap (F f) { 23 | auto F = functor::fmap(f); 24 | return [F](forward_list_of_ptr L) { 25 | return functor::fmap(F, L); 26 | }; 27 | } 28 | 29 | }; 30 | 31 | template<> struct 32 | applicative_functor :public functor { 33 | 34 | template 35 | static forward_list_of_ptr pure(A v) { 36 | auto y = applicative_functor::pure(v); 37 | return applicative_functor::pure(y); 38 | } 39 | 40 | template 41 | static std::function< forward_list_of_ptr (forward_list_of_ptr)> apply(forward_list_of_ptr> F) { 42 | return [F](forward_list_of_ptr L) { 43 | forward_list_of_ptr acc; 44 | for (auto& func : F) { 45 | for (auto& arg : L) { 46 | auto res = applicative_functor::apply(func)(arg); 47 | acc.push_front(res); 48 | } 49 | } 50 | acc.reverse(); 51 | return acc; 52 | }; 53 | }; 54 | 55 | template 56 | static std::function< forward_list_of_ptr (forward_list_of_ptr)> apply(forward_list_of_ptr F) { 57 | return [F](forward_list_of_ptr L) { 58 | forward_list_of_ptr acc; 59 | for (auto& func : F) { 60 | for (auto& arg : L) { 61 | auto res = applicative_functor::apply(func)(arg); 62 | acc.push_front(res); 63 | } 64 | } 65 | acc.reverse(); 66 | return acc; 67 | 68 | }; 69 | }; 70 | 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include 3 | #include 4 | 5 | #define ADD_FUNC(FN) std::make_pair(#FN, FN) 6 | 7 | 8 | int main(int argc, char **argv) 9 | { 10 | 11 | 12 | std::map> M = { 13 | ADD_FUNC(bracket_1), 14 | ADD_FUNC(bracket_2), 15 | ADD_FUNC(bracket_3), 16 | ADD_FUNC(bracket_4), 17 | ADD_FUNC(bracket_5), 18 | ADD_FUNC(bracket_6), 19 | ADD_FUNC(bracket_7), 20 | ADD_FUNC(bracket_8), 21 | ADD_FUNC(bracket_9), 22 | ADD_FUNC(bracket_10), 23 | ADD_FUNC(bracket_11), 24 | ADD_FUNC(eim_0), 25 | ADD_FUNC(eim_1), 26 | ADD_FUNC(eim_2), 27 | ADD_FUNC(eim_3), 28 | ADD_FUNC(eim_4), 29 | ADD_FUNC(th_0), 30 | ADD_FUNC(th_1), 31 | ADD_FUNC(th_2), 32 | ADD_FUNC(ei_0), 33 | ADD_FUNC(ei_1), 34 | ADD_FUNC(ei_2), 35 | ADD_FUNC(ei_3), 36 | ADD_FUNC(ei_4), 37 | ADD_FUNC(mbm_0), 38 | ADD_FUNC(mbm_1), 39 | ADD_FUNC(mbm_2), 40 | ADD_FUNC(mb_0), 41 | ADD_FUNC(mb_1), 42 | ADD_FUNC(mb_2), 43 | ADD_FUNC(mb_3), 44 | ADD_FUNC(mb_4), 45 | ADD_FUNC(mb_5), 46 | ADD_FUNC(fv_0), 47 | ADD_FUNC(fv_1), 48 | ADD_FUNC(fv_2), 49 | ADD_FUNC(fv_3), 50 | ADD_FUNC(fv_4), 51 | ADD_FUNC(fv_5), 52 | ADD_FUNC(fvm_0), 53 | ADD_FUNC(fvm_1), 54 | ADD_FUNC(fvm_2), 55 | ADD_FUNC(fvm_3), 56 | ADD_FUNC(fvm_4), 57 | ADD_FUNC(fvm_5), 58 | ADD_FUNC(st_0), 59 | ADD_FUNC(st_1), 60 | ADD_FUNC(stm_0), 61 | ADD_FUNC(stm_1), 62 | ADD_FUNC(stm_2), 63 | ADD_FUNC(stm_3), 64 | ADD_FUNC(stm_4), 65 | ADD_FUNC(stm_5), 66 | ADD_FUNC(stm_6), 67 | ADD_FUNC(stm_7), 68 | ADD_FUNC(stm_8), 69 | ADD_FUNC(stm_9), 70 | ADD_FUNC(stm_10), 71 | ADD_FUNC(cur_1), 72 | ADD_FUNC(mpc_1), 73 | ADD_FUNC(mpc_2), 74 | ADD_FUNC(mpc_3), 75 | ADD_FUNC(mpc_4), 76 | ADD_FUNC(mpc_5), 77 | ADD_FUNC(mpc_6), 78 | ADD_FUNC(lambda_1), 79 | ADD_FUNC(lambda_6), 80 | ADD_FUNC(lambda_7), 81 | ADD_FUNC(lambda_9), 82 | ADD_FUNC(bind_1), 83 | ADD_FUNC(bind_2), 84 | ADD_FUNC(bind_4), 85 | ADD_FUNC(bind_5), 86 | ADD_FUNC(trans_1), 87 | ADD_FUNC(trans_2), 88 | ADD_FUNC(trans_3), 89 | ADD_FUNC(trans_4), 90 | ADD_FUNC(trans_5), 91 | ADD_FUNC(trans_6), 92 | ADD_FUNC(trans_7), 93 | ADD_FUNC(trans_8), 94 | ADD_FUNC(trans_9), 95 | ADD_FUNC(functor_1), 96 | ADD_FUNC(functor_2), 97 | ADD_FUNC(functor_3), 98 | ADD_FUNC(functor_4), 99 | ADD_FUNC(functor_5), 100 | ADD_FUNC(functor_6), 101 | ADD_FUNC(functor_7), 102 | ADD_FUNC(functor_8), 103 | ADD_FUNC(functor_9), 104 | ADD_FUNC(functor_10), 105 | ADD_FUNC(functor_11), 106 | ADD_FUNC(functor_12), 107 | ADD_FUNC(apf_1), 108 | ADD_FUNC(apf_2), 109 | ADD_FUNC(apf_3), 110 | ADD_FUNC(apf_4), 111 | //ADD_FUNC(apf_5), 112 | ADD_FUNC(apf_6), 113 | ADD_FUNC(apf_7), 114 | ADD_FUNC(apf_8), 115 | ADD_FUNC(apf_9), 116 | ADD_FUNC(apf_10), 117 | ADD_FUNC(apf_11), 118 | ADD_FUNC(apf_12), 119 | ADD_FUNC(apf_13), 120 | ADD_FUNC(apf_14), 121 | ADD_FUNC(m_0), 122 | ADD_FUNC(m_1), 123 | ADD_FUNC(m_2), 124 | ADD_FUNC(m_3), 125 | ADD_FUNC(m_4), 126 | ADD_FUNC(m_5), 127 | ADD_FUNC(m_6), 128 | ADD_FUNC(m_7), 129 | ADD_FUNC(m_8), 130 | ADD_FUNC(m_9), 131 | ADD_FUNC(m_10), 132 | ADD_FUNC(m_11), 133 | ADD_FUNC(m_12), 134 | ADD_FUNC(m_13), 135 | ADD_FUNC(m_14), 136 | ADD_FUNC(m_15), 137 | ADD_FUNC(m_16) 138 | }; 139 | 140 | auto show_all = [=] (const std::string& ps) { 141 | size_t count = 1; 142 | std::cout << ps; 143 | for (auto& p : M) { 144 | std::cout << p.first << ","; 145 | if (count++ % 5 == 0) std::cout << std::endl << ps; 146 | } 147 | std::cout << std::endl; 148 | std::cout << ps << "h : history" << std::endl; 149 | std::cout << ps << "! : last command" << std::endl; 150 | std::cout << ps << "!n : command at position n" << std::endl; 151 | }; 152 | 153 | auto run_all = [=] (const std::string& ps) { 154 | size_t count = 1; 155 | for (auto& p : M) { 156 | std::cout << ps << " [" << count++ << "] " <first << std::endl; 179 | it->second(); 180 | std::cout << " *done* " << std::endl; 181 | } 182 | else { 183 | std::cout << ps << "action " << in << " not found" << std::endl; 184 | show_all(ps); 185 | } 186 | }; 187 | std::deque H; 188 | auto show_hist = [&] (const std::string& ps){ 189 | size_t index = 0; 190 | for (auto& el : H) { 191 | std::cout << ps << index << ") " << el << std::endl; 192 | index++; 193 | if (index > 10) break; 194 | } 195 | }; 196 | 197 | 198 | const std::string ps = "-> "; 199 | 200 | auto run_cmd = [&] (const std::string& in) { 201 | if (in == "q" or in == "Q") bail(ps); 202 | if (in == "?") { 203 | show_all(ps); 204 | return; 205 | } 206 | if (in == "all") { 207 | run_all(ps); 208 | return; 209 | } 210 | if (in == "h") { 211 | show_hist(ps); 212 | return; 213 | } 214 | exec(ps, in); 215 | return; 216 | }; 217 | 218 | bool keep = true; 219 | int index = 1; 220 | while (argv[index]) { 221 | run_cmd(argv[index]); 222 | index++; 223 | } 224 | while (keep) { 225 | std::cout << ps ; 226 | std::string in; 227 | std::getline(std::cin, in); 228 | if (in != "?" && in != "h" && in != "!" && !is_number(in)) H.push_front(in); 229 | std::string cmd(in); 230 | if (in == "!") { 231 | cmd = H.front(); 232 | H.pop_front(); 233 | } 234 | if (is_number(in)) { 235 | int index = std::stoi(in); 236 | if (index > -1 && index < (int) H.size()) { 237 | cmd = H[index];; 238 | } 239 | } 240 | run_cmd(cmd); 241 | } 242 | return 0; 243 | } 244 | 245 | -------------------------------------------------------------------------------- /src/makefile: -------------------------------------------------------------------------------- 1 | GCC = g++ 2 | CLANG = clang++ 3 | CC = $(GCC) 4 | CFLAGS = -c -Wall -std=c++11 -ggdb1 -lpthread 5 | LDFLAGS = 6 | 7 | LATEX = /usr/texbin/pdflatex 8 | LATEXFLAGS = -output-directory=$(DOCDIR) 9 | 10 | HTLATEX = /usr/texbin/htlatex 11 | HTLATEXFLAGS = "" "" -d 12 | 13 | 14 | #htlatex ../docs/func-idioms-c++.tex "" "" -d/tmp/ 15 | 16 | OBJDIR = ../obj 17 | EXEDIR = ../bin 18 | DOCDIR = ../docs 19 | HTMLDIR = ../html 20 | 21 | EXE = main 22 | 23 | SOURCES = $(wildcard *.cpp) 24 | INCLUDES = $(wildcard *.hpp) 25 | DOCS = $(wildcard $(DOCDIR)/*.tex) 26 | 27 | 28 | PDF = $(DOCS:.tex=.pdf) 29 | DVI = $(DOCS:.tex=.dvi) 30 | AUX = $(DOCS:.tex=.aux) 31 | LOG = $(DOCS:.tex=.log) 32 | 33 | BASEDOC = $(DOCDIR)/func-idioms-c++.tex 34 | 35 | 36 | OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.cpp=.o)) 37 | EXECUTABLE = $(addprefix $(EXEDIR)/, $(EXE)) 38 | MKTARGETDIR = @mkdir -p $(@D) 39 | 40 | #$(info $(PDF)) 41 | #$(info $(OBJECTS)) 42 | #$(info $(INCLUDES)) 43 | 44 | all : $(SOURCES) $(EXECUTABLE) $(INCLUDES) 45 | 46 | $(EXECUTABLE): $(OBJECTS) $(INCLUDES) 47 | $(MKTARGETDIR) 48 | $(CC) $(OBJECTS) -o $@ $(LDFLAGS) 49 | 50 | $(OBJDIR)/%.o: %.cpp $(INCLUDES) 51 | $(MKTARGETDIR) 52 | $(CC) $(CFLAGS) $< -o $@ 53 | 54 | 55 | docs : $(PDF) 56 | 57 | $(PDF) : $(DOCS) 58 | $(foreach var, $(DOCS), $(LATEX) $(LATEXFLAGS) $(var);) 59 | $(foreach var, $(DOCS), $(LATEX) $(LATEXFLAGS) $(var);) 60 | 61 | html : 62 | cd $(HTMLDIR); \ 63 | $(HTLATEX) $(BASEDOC) 64 | 65 | clean: 66 | rm -f $(OBJECTS) $(EXEDIR)/core $(EXECUTABLE) 67 | 68 | docsclean: 69 | rm -f $(PDF) $(AUX) $(DVI) $(LOG) 70 | 71 | realclean: 72 | -rm -f $(OBJECTS) $(EXEDIR)/core $(EXECUTABLE) 73 | -rm -f *~ 74 | -rm -f $(PDF) $(AUX) $(DVI) $(LOG) 75 | -rm $(DOCDIR)/*~ $(DOCDIR)/*log 76 | -rmdir $(OBJDIR) 77 | -rmdir $(EXEDIR) 78 | 79 | -------------------------------------------------------------------------------- /src/map.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "map.hpp" 3 | 4 | int map_1() 5 | { 6 | std::list L = {-1,2,33,4,50,90, -7,23}; 7 | std::for_each(L.begin(), L.end(), [](int elem) { std::cout << elem << std::endl;}); 8 | return 0; 9 | } 10 | 11 | 12 | 13 | int map_2() 14 | { 15 | std::forward_list K = {-1,2,33,4,50,90, -7,23}; 16 | std::function f2 = [] (int x) {return 2 * x + 8;}; 17 | std::forward_list L = map(f2, K); 18 | std::for_each(L.begin(), L.end(), [](int elem) { std::cout << elem << std::endl;}); 19 | std::for_each(K.begin(), K.end(), [](int elem) { std::cout << elem << std::endl;}); 20 | return 0; 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/map.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__map__h 2 | #define h__map__h 3 | 4 | template 5 | std::forward_list map (std::function op, const std::forward_list& L) 6 | { 7 | std::forward_list acc; 8 | for (auto &v : L) { 9 | acc.push_front(op(v)); 10 | } 11 | acc.reverse(); 12 | return acc; 13 | } 14 | 15 | template 16 | auto map (F f, const std::forward_list& L) -> std::forward_list 17 | { 18 | std::forward_list H; 19 | std::transform(L.begin(), L.end(), std::front_inserter(H), f); 20 | H.reverse(); 21 | return H; 22 | } 23 | 24 | template 25 | std::list map (F op, const std::list& L) 26 | { 27 | std::list acc; 28 | for (auto &v : L) { 29 | acc.push_back(op(v)); 30 | } 31 | return acc; 32 | } 33 | 34 | template 35 | auto map (F f, const std::list& L) -> std::list 36 | { 37 | std::list H; 38 | std::transform(L.begin(), L.end(), std::back_inserter(H), f); 39 | return H; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/maybe.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "maybe.hpp" 4 | 5 | 6 | ////////////////////////////////////////////////////// 7 | 8 | int mb_0() 9 | { 10 | auto val = just("hello"); 11 | std::cerr << val << std::endl; 12 | 13 | auto val2 = none(); 14 | std::cerr << val2 << std::endl; 15 | return 0; 16 | } 17 | 18 | int mb_1() 19 | { 20 | 21 | auto f = [](){return none();}; 22 | auto g = [](){return just(std::make_pair(34,"hello"));}; 23 | auto v1 = f(); 24 | auto v2 = g(); 25 | 26 | if (v1 == Maybe::None()) { 27 | std::cerr << "v1 is none..." << std::endl; 28 | } 29 | 30 | if (v2 != NONE) { 31 | std::cerr << "v2 is not none..." << std::endl; 32 | } 33 | 34 | std::cerr << v1 << "," << v2 << std::endl; 35 | 36 | if (v1 == none()) { 37 | std::cerr << "none : " << v1 << std::endl; 38 | } 39 | 40 | if (v1 != none()) { 41 | std::cerr << "none : " << v1 << "!=" << none() << std::endl; 42 | } 43 | 44 | 45 | if (v1 == v2) { 46 | std::cerr << "v1==v2 ?? -> " << v1 << " " << v2 << std::endl; 47 | } 48 | 49 | if (v2 != v1) { 50 | std::cerr << "v1!=v2 ?? -> " << v1 << " " << v2 << std::endl; 51 | } 52 | 53 | 54 | if (v2 != just(1)) { 55 | std::cerr << v2 << " != " << 1 << std::endl; 56 | } 57 | 58 | if (v2 == just(std::make_pair(34,"hello"))) { 59 | std::cerr << v2 << "==" << just(std::make_pair(34,"hello")) << std::endl; 60 | } 61 | 62 | if (just(std::make_pair(34,"hello")) == v2) { 63 | std::cerr << just(std::make_pair(34,"hello")) << "==" << v2 << std::endl; 64 | } 65 | 66 | if (just(std::make_pair(24,"hello")) != v2) { 67 | std::cerr << just(std::make_pair(24,"hello")) << "!=" << v2 << std::endl; 68 | } 69 | 70 | if (g() == g()) { 71 | std::cerr << "g() :" << g() << std::endl; 72 | } 73 | 74 | if (f() == f()) { 75 | std::cerr << "f() " << f() << std::endl; 76 | } 77 | 78 | if (Maybe::None() == Maybe::None()) { 79 | std::cerr << Maybe::None() << " == " << Maybe::None() << std::endl; 80 | } 81 | 82 | if (Maybe::None() != Maybe::None()) { 83 | std::cerr << Maybe::None() << " != " << Maybe::None() << std::endl; 84 | } 85 | 86 | 87 | auto p = Maybe>::None(); 88 | std::function fint = [] (int x) { return 2*x-3;}; 89 | std::cerr << p << std::endl; 90 | //if (fint == fint) { 91 | // std::cerr << "p == p for function" << std::endl; 92 | //} 93 | return 0; 94 | } 95 | 96 | int mb_2() 97 | { 98 | 99 | auto g = [] (int x){ 100 | if (x > 0) return just(x); 101 | return none(); 102 | }; 103 | 104 | auto f = [] (Maybe m) { 105 | if (m != m.None()) { 106 | std::cerr << "hey this is set : " << m << std::endl; 107 | } 108 | return m; 109 | }; 110 | 111 | std::cerr << g(23) << std::endl; 112 | std::cerr << g(-23) << std::endl; 113 | f(g(23)); 114 | f(g(-23)); 115 | 116 | return 0; 117 | } 118 | 119 | int mb_3() 120 | { 121 | auto v1 = just(34); 122 | auto v2 = v1; 123 | if (v1 == v2) { 124 | std::cerr << "const copy worked : " << v1 << " == " << v2 << std::endl; 125 | } 126 | auto v3 = just(45); 127 | std::cerr << "v 3 : " << v3 << std::endl; 128 | //--> not allowed v3 = v2; 129 | //std::cerr << "v 3 : " << v3 << std::endl; 130 | 131 | return 0; 132 | } 133 | 134 | int mb_4() 135 | { 136 | auto v1 = just(34); 137 | 138 | std::cerr << "v1: " << v1 << std::endl; 139 | std::cerr << "*v1: " << *v1 << std::endl; 140 | 141 | auto v2 = none(); 142 | 143 | std::cerr << "v2: " << v2 << std::endl; 144 | std::cerr << "*v2: " << *v2 << std::endl; 145 | if (v2 == v2.None()) { 146 | std::cerr << "v2 is None !!" << std::endl; 147 | } 148 | 149 | return 0; 150 | } 151 | 152 | int mb_5() 153 | { 154 | std::list L = {1,2,3,4,5}; 155 | auto l1 = just(L); 156 | std::cerr << l1 << std::endl; 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /src/maybe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__maybe__h 2 | #define h__maybe__h 3 | 4 | 5 | template 6 | struct Maybe { 7 | typedef A value_type; 8 | 9 | Maybe(const Maybe& o) : val(o.val){} 10 | 11 | void operator=(const Maybe& o) = delete; 12 | 13 | std::ostream& pp(std::ostream& strm) const { 14 | strm << "Maybe<" << typeid(A).name() << ">"; 15 | if (val.second) { 16 | strm << "[Just(" << val.first << ")]"; 17 | } 18 | else { 19 | strm << "[None]"; 20 | } 21 | return strm; 22 | } 23 | 24 | static Maybe Just(const A& a) { 25 | return Maybe(a); 26 | } 27 | 28 | static Maybe None() { 29 | return Maybe(); 30 | } 31 | 32 | bool eq (const Maybe& m) const { 33 | return (val.second == m.val.second) && (val.first == m.val.first); 34 | } 35 | 36 | const A& operator*() { 37 | return val.first; 38 | } 39 | 40 | bool none() const { 41 | return (val.second == false); 42 | } 43 | 44 | private: 45 | 46 | Maybe() : val(std::make_pair(A(), false)) {} 47 | explicit Maybe(const A& a) : val(std::make_pair(a,true)){} 48 | const std::pair val; 49 | 50 | }; 51 | 52 | 53 | template 54 | Maybe just(A val) { 55 | return Maybe::Just(val); 56 | } 57 | 58 | template 59 | Maybe none() { 60 | return Maybe::None(); 61 | } 62 | 63 | template 64 | std::ostream& operator<<(std::ostream& strm, const Maybe& M) 65 | { 66 | M.pp(strm); 67 | return strm; 68 | } 69 | 70 | template 71 | bool operator==(const Maybe& l, const Maybe& r) { 72 | if (l.eq(l.None()) && r.eq(r.None())) return true; 73 | return false; 74 | } 75 | 76 | template 77 | bool operator==(const Maybe& l, const Maybe& r) { 78 | return l.eq(r); 79 | } 80 | 81 | template 82 | bool operator!=(const Maybe& l, const Maybe& r) { 83 | return !(l==r); 84 | } 85 | 86 | #define NONE Maybe::None() 87 | 88 | 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/maybe_monad.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "maybe_monad.hpp" 4 | 5 | 6 | 7 | int mbm_0() 8 | { 9 | auto f = [] (int x) { 10 | return "xxxxxx"; 11 | }; 12 | 13 | auto v1 = just(10); 14 | auto v2 = functor::fmap(f, v1); 15 | auto v3 = functor::fmap(f)(v1); 16 | std::cerr << v1 << std::endl; 17 | std::cerr << v2 << std::endl; 18 | std::cerr << v3 << std::endl; 19 | if (v2 == v3) { 20 | std::cerr << v2 << " == " << v3 << std::endl; 21 | } 22 | return 0; 23 | } 24 | 25 | int mbm_1() 26 | { 27 | typedef std::pair arg_t; 28 | 29 | Maybe L = just(std::make_pair(9,std::string("hello"))); 30 | 31 | auto get_string = [] (arg_t arg) { 32 | return arg.second; 33 | }; 34 | //cannot be instantiated 35 | //auto pm = none(); 36 | auto lm = applicative_functor::pure(get_string); 37 | auto v1 = applicative_functor::apply(lm, L); 38 | std::cerr << v1 << std::endl; 39 | 40 | auto v2 = applicative_functor::apply(lm)(L); 41 | std::cerr << v2 << std::endl; 42 | 43 | return 0; 44 | } 45 | 46 | int mbm_2() 47 | { 48 | 49 | auto val1 = just(56); 50 | auto lambda = [](int x) { 51 | if ( x > 0) return just(std::string("good !")); 52 | return none(); 53 | }; 54 | auto val2 = monad::bind(val1, lambda); 55 | std::cerr << val1 << std::endl; 56 | std::cerr << val2 << std::endl; 57 | 58 | std::cerr << monad::bind(just(-89), lambda) << std::endl; 59 | 60 | std::cerr << monad::bind(monad::bind(just(-89), lambda), 61 | [](const std::string& val) { 62 | std::cerr<<"===> val" << std::endl; 63 | return just(val); 64 | }); 65 | std::cerr << std::endl; 66 | std::cerr << monad::bind(monad::bind(just(89), lambda), 67 | [](const std::string& val) { 68 | std::cerr<<"===> val " << val << std::endl; 69 | return just(val); 70 | }); 71 | 72 | 73 | return 0; 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/maybe_monad.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__maybe_monad__h 2 | #define h__maybe_monad__h 3 | #include "maybe.hpp" 4 | #include "functor.hpp" 5 | #include "applicative_functor.hpp" 6 | #include "monad.hpp" 7 | 8 | template<> 9 | struct functor { 10 | 11 | template 12 | static auto fmap(lambda f) ->std::function (Maybe) > { 13 | return [f](Maybe m) -> Maybe { 14 | if (m == m.None()) { 15 | return Maybe::None(); 16 | } 17 | return just(f(*m)); 18 | }; 19 | } 20 | 21 | template 22 | 23 | static auto retval(lambda f, Maybe m) -> Maybe; 24 | 25 | template 26 | static auto fmap(lambda f, Maybe m) -> Maybe { 27 | return fmap(f)(m); 28 | } 29 | 30 | }; 31 | 32 | template<> 33 | struct applicative_functor : public functor 34 | { 35 | template 36 | static Maybe pure(A val) { 37 | return just(val); 38 | }; 39 | 40 | template 41 | static auto apply(Maybe F , Maybe m) -> decltype(functor::retval(*F, m)) { 42 | // I can't call F.None() because lambda's don't have a default constructor..; 43 | //std::function::retval(*F, m))::value_type (A)> ff = *F; 44 | return functor::fmap(*F, m); 45 | }; 46 | 47 | template 48 | static auto apply(Maybe F) -> std::function::retval(*F, Maybe::Just(A()))) (Maybe)> { 49 | return [F] (Maybe m) { 50 | return apply(F,m); 51 | }; 52 | }; 53 | }; 54 | 55 | template <> 56 | struct monad : public applicative_functor 57 | { 58 | template 59 | static Maybe mreturn (A val) { 60 | return applicative_functor::pure(val); 61 | } 62 | 63 | 64 | template 65 | static auto bind(Maybe m) { 66 | return [&m](lambda F) { 67 | if (m == m.None()) { 68 | //constructors are private so I do this in a bit of a rond-about way. 69 | return Maybe::None(); 70 | } 71 | return F(*m); 72 | }; 73 | }; 74 | 75 | template 76 | static auto bind(Maybe m, lambda F) -> decltype(Maybe::None()) { 77 | return bind(m)(F); 78 | }; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/monad.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "monad.hpp" 3 | #include "show.hpp" 4 | 5 | 6 | template 7 | auto mapM (F f, std::forward_list L) -> decltype(f(A())) 8 | { 9 | typedef typename decltype(f(A()))::value_type ret_t; 10 | L.reverse(); 11 | auto concat = [] (std::forward_list L, std::forward_list R) { 12 | L.splice_after(L.before_begin(), R); 13 | return L; 14 | }; 15 | auto op = std::bind(concat, std::placeholders::_1, std::bind(f, std::placeholders::_2)); 16 | return std::accumulate(L.begin(), L.end(), std::forward_list(), op);; 17 | } 18 | 19 | int m_0() 20 | { 21 | auto show = [] (int v) { std::cout << v << ","; return v;}; 22 | typedef std::forward_list list_t; 23 | list_t L = {1,-6,23,78,45,13}; 24 | auto l1 = [] (int y) {return list_t ({2*y+1, -y, -2*y + 1});}; 25 | std::cerr << "before ...." << std::endl; 26 | map(show, L); 27 | std::cerr << std::endl << "after ...." << std::endl; 28 | map(show, mapM(l1, L)); 29 | return 0; 30 | } 31 | 32 | int m_1() 33 | { 34 | auto show = [] (std::tuple v) { std::cout << v << ","; return v;}; 35 | static char digits[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }; 36 | typedef std::forward_list> list_t; 37 | auto op = [] (int y) {return list_t({std::make_tuple(y, digits[abs(y)%10])});}; 38 | map(show, mapM(op, std::forward_list({1,-6,23,78,45,13}))); 39 | 40 | auto res = map(op, std::forward_list({1,-6,23,78,45,13})); 41 | std::cout << std::endl << "-----------------" << std::endl; 42 | for (auto& el : res) { 43 | std::cout << "["; 44 | map(show, el); 45 | std::cout << "], "; 46 | } 47 | return 0; 48 | } 49 | 50 | 51 | int m_2() 52 | { 53 | auto show = [] (int v) { std::cout << v << ","; return v;}; 54 | std::forward_list L = {1,3,45,78}; 55 | auto op = [] (int x) { 56 | std::forward_list R = {x , -x}; 57 | return R; 58 | }; 59 | 60 | auto R = monad::bind(L)(op); 61 | map (show, R); 62 | return 0; 63 | } 64 | 65 | int m_3() 66 | { 67 | 68 | std::function(int)> plus = [] (int x) { 69 | return [x] (int y) { 70 | return x + y; 71 | }; 72 | }; 73 | 74 | std::function(int)> mult = [] (int x) { 75 | return [=] (int y) { 76 | return x * y; 77 | }; 78 | }; 79 | 80 | auto f = mult(5); 81 | auto g = plus(3); 82 | auto res = functor::fmap(f, g); 83 | std::cout << "res(8) : " << res(8) << std::endl; 84 | 85 | std::function uncur = [plus] (int x, int y) { return plus(x)(y);}; 86 | auto res2 = monad::bind(f, uncur); 87 | std::cout << " res (10) : " << res(10) << std::endl; 88 | return 0; 89 | } 90 | 91 | int m_4() 92 | { 93 | 94 | std::forward_list L = {1,2}; 95 | auto op = [](int x) { 96 | std::forward_list R = {'a' , 'b'}; 97 | return R; 98 | }; 99 | 100 | auto R = monad::bind(L)(op); 101 | for (auto& v: R) { 102 | std::cout << v << ","; 103 | } 104 | std::cout << std::endl; 105 | 106 | return 0; 107 | } 108 | 109 | int m_5() 110 | { 111 | std::forward_list L = {1,2}; 112 | 113 | auto v1 = monad::pure(-34); 114 | std::cout << v1 << std::endl; 115 | 116 | auto v2 = monad::mreturn(3400); 117 | std::cout << v2 << std::endl; 118 | 119 | return 0; 120 | } 121 | 122 | // 123 | // std::forward_list 124 | //monod law [m >>= return = m] 125 | // 126 | int m_6() 127 | { 128 | std::forward_list L = {1,2}; 129 | auto op = [](int x) { 130 | return monad::pure(x); 131 | }; 132 | auto R = monad::bind(L)(op); 133 | std::cout << R << std::endl; 134 | return 0; 135 | } 136 | 137 | // 138 | // std::forward_list 139 | // monad law : [return a >>= k = k] 140 | // 141 | int m_7() 142 | { 143 | auto op = [](int x) { 144 | return monad::pure(2 * x); 145 | }; 146 | auto v = 7896; 147 | auto L = monad::bind(monad::pure(v))(op); 148 | auto R = op(v); 149 | std::cerr << " L = R : " << L << " = " << R << std::endl; 150 | return 0; 151 | } 152 | // 153 | // std::forward_list 154 | // monad law : [m >>= (\x->k x >>= h) = (m >>= k) >>= h] 155 | // 156 | int m_8() 157 | { 158 | std::forward_list m = {1,2}; 159 | auto k = [](int x) { 160 | return monad::pure(2 * x + 9); 161 | }; 162 | auto h = [](int x) { 163 | return monad::pure((x - 9)/2); 164 | }; 165 | auto R1 = monad::bind(m)(k); 166 | auto R2 = monad::bind(R1)(h); 167 | std::cerr << " m " << m << std::endl; 168 | std::cerr << " R1 " << R1 << std::endl; 169 | std::cerr << " R2 " << R2 << std::endl; 170 | 171 | // [\x->k x >>= h] 172 | std::function < std::forward_list(int) > lambda = [k,h](int x) { 173 | return monad::bind(k(x))(h); 174 | }; 175 | auto R3 = monad::bind(m)(lambda); 176 | std::cerr << "R3 : " << R3 << std::endl; 177 | return 0; 178 | } 179 | 180 | 181 | // 182 | // std::list 183 | //monod law [m >>= return = m] 184 | // 185 | int m_9() 186 | { 187 | std::list L = {1,2}; 188 | auto op = [](int x) { 189 | return monad::pure(x); 190 | }; 191 | auto R = monad::bind(L)(op); 192 | std::cout << R << std::endl; 193 | return 0; 194 | } 195 | 196 | // 197 | // std::list 198 | // monad law : [return a >>= k = k] 199 | // 200 | int m_10() 201 | { 202 | auto op = [](int x) { 203 | return monad::pure(2 * x); 204 | }; 205 | auto v = 7896; 206 | auto L = monad::bind(monad::pure(v))(op); 207 | auto R = op(v); 208 | std::cerr << " L = R : " << L << " = " << R << std::endl; 209 | return 0; 210 | } 211 | // 212 | // std::list 213 | // monad law : [m >>= (\x->k x >>= h) = (m >>= k) >>= h] 214 | // 215 | int m_11() 216 | { 217 | std::list m = {1,2}; 218 | auto k = [](int x) { 219 | return monad::pure(2 * x + 9); 220 | }; 221 | auto h = [](int x) { 222 | return monad::pure((x - 9)/2); 223 | }; 224 | auto R1 = monad::bind(m)(k); 225 | auto R2 = monad::bind(R1)(h); 226 | std::cerr << " m " << m << std::endl; 227 | std::cerr << " R1 " << R1 << std::endl; 228 | std::cerr << " R2 " << R2 << std::endl; 229 | 230 | // [\x->k x >>= h] 231 | std::function < std::list(int) > lambda = [k,h](int x) { 232 | return monad::bind(k(x))(h); 233 | }; 234 | auto R3 = monad::bind(m)(lambda); 235 | std::cerr << "R3 : " << R3 << std::endl; 236 | return 0; 237 | } 238 | 239 | // 240 | // std::shared_ptr 241 | //monod law [m >>= return = m] 242 | // 243 | int m_12() 244 | { 245 | std::shared_ptr L = monad::pure(10); 246 | auto op = [](int x) { 247 | return monad::pure(x); 248 | }; 249 | auto R = monad::bind(L)(op); 250 | std::cout << R << std::endl; 251 | std::cout << op(10) << std::endl; 252 | return 0; 253 | } 254 | 255 | // 256 | // std::shared_ptr 257 | // monad law : [return a >>= k = k] 258 | // 259 | int m_13() 260 | { 261 | auto op = [](int x) { 262 | return monad::pure(2 * x); 263 | }; 264 | auto v = 7896; 265 | auto L = monad::bind(monad::pure(v))(op); 266 | auto R = op(v); 267 | std::cerr << " L = R : " << L << " = " << R << std::endl; 268 | return 0; 269 | } 270 | // 271 | // std::shared_ptr 272 | // monad law : [m >>= (\x->k x >>= h) = (m >>= k) >>= h] 273 | // 274 | int m_14() 275 | { 276 | std::shared_ptr m = monad::pure(10); 277 | auto k = [](int x) { 278 | return monad::pure(2 * x + 9); 279 | }; 280 | auto h = [](int x) { 281 | return monad::pure((x - 9)/2); 282 | }; 283 | auto R1 = monad::bind(m)(k); 284 | auto R2 = monad::bind(R1)(h); 285 | std::cerr << " m " << m << std::endl; 286 | std::cerr << " R1 " << R1 << std::endl; 287 | std::cerr << " R2 " << R2 << std::endl; 288 | 289 | // [\x->k x >>= h] 290 | std::function < std::shared_ptr(int) > lambda = [k,h](int x) { 291 | return monad::bind(k(x))(h); 292 | }; 293 | auto R3 = monad::bind(m)(lambda); 294 | std::cerr << "R3 : " << R3 << std::endl; 295 | return 0; 296 | } 297 | 298 | 299 | int m_15() 300 | { 301 | std::function f = [](int x) { return new int(3*x - 56);}; 302 | int* M = new int(90); 303 | int* retval = monad::bind(M, f); 304 | std::cerr << " M :" << *M << " ==> " << *retval << std::endl; 305 | 306 | return 0; 307 | } 308 | 309 | 310 | int m_16() 311 | { 312 | 313 | return 0; 314 | } 315 | -------------------------------------------------------------------------------- /src/monad.hpp: -------------------------------------------------------------------------------- 1 | #ifndef H__MONAD__H 2 | #define H__MONAD__H 3 | #include "applicative_functor.hpp" 4 | #include "raw_pointer.hpp" 5 | 6 | template class F> 7 | struct monad : public applicative_functor 8 | { 9 | template static F mreturn (A val) { 10 | return applicative_functor::pure(val); 11 | } 12 | 13 | template 14 | static std::function < F (std::function< F (A) > ) > bind(F val); 15 | 16 | }; 17 | //--------------------------------------- monad implementation------------------------------- 18 | // 19 | // std::forward_list 20 | // 21 | 22 | template<> struct monad : public applicative_functor { 23 | 24 | template 25 | static std::function < std::forward_list (std::function< std::forward_list (A) > ) > bind(std::forward_list M) { 26 | return [M](std::function (A)> f) { 27 | std::forward_list R; 28 | std::forward_list> res = map(f, M); 29 | res.reverse(); 30 | for (auto& list : res) { 31 | R.splice_after(R.before_begin(), list);//concatenate 32 | } 33 | return R; 34 | }; 35 | } 36 | 37 | template static std::forward_list mreturn (A val) { 38 | return applicative_functor::pure(val); 39 | } 40 | 41 | }; 42 | 43 | //--------------------------------------------------------------------------------------------------------- 44 | // 45 | // std::list 46 | // 47 | 48 | template<> struct monad : public applicative_functor { 49 | 50 | template 51 | static std::function < std::list (std::function< std::list (A) > ) > bind(std::list M) { 52 | return [M](std::function (A)> f) { 53 | std::list R; 54 | std::list> res = map(f, M); 55 | for (auto& list : res) { 56 | R.insert(R.end(), list.begin(), list.end()); 57 | } 58 | return R; 59 | }; 60 | } 61 | 62 | template static std::list mreturn (A val) { 63 | return applicative_functor::pure(val); 64 | } 65 | 66 | }; 67 | //--------------------------------------------------------------------------------------------------------- 68 | // 69 | // std::shared_ptr 70 | // 71 | 72 | template<> struct monad : public applicative_functor { 73 | 74 | template 75 | static std::function < std::shared_ptr (std::function< std::shared_ptr (A) > ) > bind(std::shared_ptr M) { 76 | return [M](std::function (A)> f) { 77 | if (M) { 78 | return f(*M); 79 | } 80 | return std::shared_ptr(); 81 | }; 82 | } 83 | 84 | template static std::shared_ptr mreturn (A val) { 85 | return applicative_functor::pure(val); 86 | } 87 | 88 | }; 89 | 90 | //----------------------------------------------------------------------------------------- 91 | // 92 | // unary functions 93 | // 94 | template<> 95 | struct monad : public applicative_functor { 96 | 97 | template 98 | static std::function bind(std::function h, std::function < R (A,B)> f) { 99 | return [f,h] (A x) { 100 | return f(h(x), x); 101 | }; 102 | }; 103 | 104 | template 105 | static auto bind(F h, R f) { 106 | return [f,h] (A x) { 107 | return f(h(x), x); 108 | }; 109 | }; 110 | 111 | 112 | }; 113 | 114 | //----------------------------------------------------------------------------------------- 115 | // 116 | // raw pointer 117 | // 118 | 119 | template<> 120 | struct monad : public applicative_functor { 121 | 122 | template 123 | static B* bind(A* M, std::function f) { 124 | if (M) { 125 | return f(*M); 126 | } 127 | return static_cast(nullptr); 128 | } 129 | 130 | template static A* mreturn (A val) { 131 | return new A(val); 132 | } 133 | }; 134 | 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /src/mpc.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "mpc.hpp" 3 | #include "functor.hpp" 4 | #include "applicative_functor.hpp" 5 | #include "show.hpp" 6 | #include "curry.hpp" 7 | 8 | plist_t item_f(std::string s) { 9 | if (s.length() == 0) { 10 | return plist_t(); 11 | } 12 | return plist_t({ppair_t(s.front(), s.substr(1))}); 13 | } 14 | 15 | int mpc_1() 16 | { 17 | ppair_t y ('c', "hello"); 18 | std::cout << y << std::endl; 19 | plist_t L = {y}; 20 | L.push_back(ppair_t('p', "done")); 21 | std::cout << L << std::endl; 22 | parser_t F = [=](std::string s) { return L;}; 23 | std::cout << F << std::endl; 24 | 25 | Parser P(F); 26 | std::cout << P << std::endl; 27 | 28 | auto res = parse (P)("hello"); 29 | std::cout << "->" << res << std::endl; 30 | return 0; 31 | } 32 | 33 | int mpc_2() 34 | { 35 | 36 | Parser item(item_f); 37 | auto res = parse (item) ("hello"); 38 | std::cout << res << std::endl; 39 | auto res1 = parse (item) (""); 40 | std::cout << res1 << std::endl; 41 | return 0; 42 | } 43 | 44 | int mpc_3 () 45 | { 46 | std::function idc = [] (char v) { return v;}; 47 | 48 | Parser item(item_f); 49 | auto res = parse (item) ("hello"); 50 | std::cout << res << std::endl; 51 | 52 | auto res1 = parse (functor::fmap(idc)(item)) ("hello"); 53 | std::cout << res1 << std::endl; 54 | 55 | return 1; 56 | } 57 | 58 | template<> 59 | struct applicative_functor : public functor 60 | { 61 | 62 | template 63 | static Parser pure(A val) { 64 | parser_t rb = [=](std::string s) { 65 | ppair_t y (val, s); 66 | plist_t L = {y}; 67 | return L; 68 | }; 69 | return Parser(rb); 70 | }; 71 | 72 | template 73 | static std::function< Parser (Parser)> apply(Parser F) { 74 | return [=](Parser L) { 75 | 76 | parser_t rb = [=] (std::string input) { 77 | auto lambda_parse = parse(F)(input); 78 | plist_t results; 79 | for (auto& el : lambda_parse) { 80 | 81 | auto csp = parse(L)(std::get<1>(el)); 82 | 83 | std::function< ppair_t (ppair_t)> lab = [=] (ppair_t v) { 84 | return ppair_t(std::get<0>(el) (std::get<0>(v)), std::get<1>(v)); 85 | }; 86 | plist_t l = functor::fmap(lab)(csp); 87 | results.insert(results.end(), l.begin(), l.end()); 88 | } 89 | 90 | return results; 91 | }; 92 | 93 | return Parser(rb); 94 | }; 95 | }; 96 | }; 97 | 98 | int mpc_4() 99 | { 100 | auto j = applicative_functor::pure(1); 101 | std::cout << j << std::endl; 102 | auto res = parse(j)("hello"); 103 | std::cout << res << std::endl; 104 | return 0; 105 | } 106 | 107 | int mpc_5() 108 | { 109 | Parser item(item_f); 110 | typedef char T1; 111 | auto f = [=] (T1 c){ return std::make_tuple(c);}; 112 | typedef decltype(f(T1())) ret_t; 113 | auto ll1 = applicative_functor::pure(f); 114 | auto ap1 = applicative_functor::apply(ll1)(item); 115 | auto res1 = parse(ap1)("hello"); 116 | std::cout << res1 << std::endl; 117 | return 0; 118 | } 119 | 120 | int mpc_6() 121 | { 122 | Parser item(item_f); 123 | 124 | typedef char T1; 125 | typedef char T2; 126 | 127 | auto ff = [=] (T1 a, T2 b){ return std::make_tuple(a,b);}; 128 | 129 | typedef decltype(ff(T1(), T2())) ret_t; 130 | 131 | auto cff = curry(ff); 132 | auto cffl = applicative_functor::pure(cff); 133 | auto C = applicative_functor::apply(cffl)(item); 134 | auto J = applicative_functor::apply(C)(item); 135 | auto res1 = parse(J)("hello"); 136 | std::cout << res1 << std::endl; 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /src/mpc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__mpc__h 2 | #define h__mpc__h 3 | 4 | template 5 | using ppair_t = std::tuple; 6 | 7 | template 8 | std::ostream& operator<<(std::ostream& strm, const ppair_t& p) 9 | { 10 | return strm << "(" << std::get<0>(p) << "," << std::get<1>(p) << ")"; 11 | } 12 | 13 | template 14 | using plist_t = std::list>; 15 | 16 | template 17 | std::ostream& operator<<(std::ostream& strm, const plist_t& L) 18 | { 19 | strm<<"["; 20 | size_t l = 0; 21 | for (auto& v: L) { 22 | strm << v; 23 | if (++l % 10) { 24 | strm << ","; 25 | } 26 | else { 27 | strm << std::endl; 28 | } 29 | } 30 | return strm<<"]"; 31 | } 32 | 33 | 34 | template 35 | using parser_t = std::function< plist_t (std::string)>; 36 | 37 | template 38 | std::ostream& operator<<(std::ostream& strm, const parser_t& F) 39 | { 40 | return strm << "(std::string) -> [(" << typeid(a).name() << ", std::string)]"; 41 | } 42 | 43 | template 44 | struct Parser 45 | { 46 | 47 | Parser(const parser_t& p) : p(p){} 48 | Parser(const Parser& o) : p(o.p){} 49 | const Parser& operator=(const Parser& o) { 50 | if (this != &o) { 51 | p = o.p; 52 | } 53 | return *this; 54 | } 55 | ~Parser() {} 56 | 57 | inline parser_t operator ()() const { 58 | return p; 59 | } 60 | 61 | std::ostream& operator()(std::ostream& o) const { 62 | return o << "Parser (" << p << ")"; 63 | } 64 | private: 65 | 66 | parser_t p; 67 | 68 | }; 69 | 70 | template 71 | std::ostream& operator<<(std::ostream& strm, const Parser& p) 72 | { 73 | return p(strm); 74 | } 75 | 76 | template 77 | parser_t parse (Parser P) { 78 | return P(); 79 | }; 80 | 81 | extern plist_t item_f(std::string s); 82 | 83 | #include "functor.hpp" 84 | 85 | template<> 86 | struct functor 87 | { 88 | 89 | template 90 | static std::function < Parser (Parser)> fmap(std::function f) { 91 | return [=] (Parser P) { 92 | parser_t pb = [=] (std::string inp) { 93 | std::function< ppair_t (ppair_t)> lab = [=] (ppair_t v) { 94 | return ppair_t(f (std::get<0>(v)), std::get<1>(v)); 95 | }; 96 | return functor::fmap(lab)(parse(P)(inp)); 97 | }; 98 | return Parser(pb); 99 | }; 100 | }; 101 | }; 102 | 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/proto.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __proto__ 2 | #define __proto__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | extern int th_0(); 16 | extern int th_1(); 17 | extern int th_2(); 18 | 19 | 20 | extern int eim_0(); 21 | extern int eim_1(); 22 | extern int eim_2(); 23 | extern int eim_3(); 24 | extern int eim_4(); 25 | 26 | extern int ei_0(); 27 | extern int ei_1(); 28 | extern int ei_2(); 29 | extern int ei_3(); 30 | extern int ei_4(); 31 | 32 | extern int mb_0(); 33 | extern int mb_1(); 34 | extern int mb_2(); 35 | extern int mb_3(); 36 | extern int mb_4(); 37 | extern int mb_5(); 38 | 39 | extern int mbm_0(); 40 | extern int mbm_1(); 41 | extern int mbm_2(); 42 | 43 | extern int fv_0(); 44 | extern int fv_1(); 45 | extern int fv_2(); 46 | extern int fv_3(); 47 | extern int fv_4(); 48 | extern int fv_5(); 49 | 50 | extern int fvm_0(); 51 | extern int fvm_1(); 52 | extern int fvm_2(); 53 | extern int fvm_3(); 54 | extern int fvm_4(); 55 | extern int fvm_5(); 56 | 57 | 58 | extern int st_0(); 59 | extern int st_1(); 60 | 61 | extern int stm_0(); 62 | extern int stm_1(); 63 | extern int stm_2(); 64 | extern int stm_3(); 65 | extern int stm_4(); 66 | extern int stm_5(); 67 | extern int stm_6(); 68 | extern int stm_7(); 69 | extern int stm_8(); 70 | extern int stm_9(); 71 | extern int stm_10(); 72 | 73 | 74 | extern int bracket_1(); 75 | extern int bracket_2(); 76 | extern int bracket_3(); 77 | extern int bracket_4(); 78 | extern int bracket_5(); 79 | extern int bracket_6(); 80 | extern int bracket_7(); 81 | extern int bracket_8(); 82 | extern int bracket_9(); 83 | extern int bracket_10(); 84 | extern int bracket_11(); 85 | 86 | extern int cur_1(); 87 | 88 | extern int lambda_1(); 89 | extern int lambda_6(); 90 | extern int lambda_7(); 91 | extern int lambda_9(); 92 | 93 | 94 | extern int trans_1(); 95 | extern int trans_2(); 96 | extern int trans_3(); 97 | extern int trans_4(); 98 | extern int trans_5(); 99 | extern int trans_6(); 100 | extern int trans_7(); 101 | extern int trans_8(); 102 | extern int trans_9(); 103 | 104 | 105 | extern int functor_1(); 106 | extern int functor_2(); 107 | extern int functor_3(); 108 | extern int functor_4(); 109 | extern int functor_5(); 110 | extern int functor_6(); 111 | extern int functor_7(); 112 | extern int functor_8(); 113 | extern int functor_9(); 114 | 115 | extern int functor_10(); 116 | extern int functor_11(); 117 | extern int functor_12(); 118 | extern int functor_9(); 119 | 120 | extern int apf_1(); 121 | extern int apf_2(); 122 | extern int apf_3(); 123 | extern int apf_4(); 124 | extern int apf_5(); 125 | extern int apf_6(); 126 | extern int apf_7(); 127 | extern int apf_8(); 128 | extern int apf_9(); 129 | extern int apf_10(); 130 | extern int apf_11(); 131 | extern int apf_12(); 132 | extern int apf_13(); 133 | extern int apf_14(); 134 | 135 | extern int m_0(); 136 | extern int m_1(); 137 | extern int m_2(); 138 | extern int m_3(); 139 | extern int m_4(); 140 | extern int m_5(); 141 | extern int m_6(); 142 | extern int m_7(); 143 | extern int m_8(); 144 | extern int m_9(); 145 | extern int m_10(); 146 | extern int m_11(); 147 | extern int m_12(); 148 | extern int m_13(); 149 | extern int m_14(); 150 | extern int m_15(); 151 | extern int m_16(); 152 | 153 | extern int w_1(); 154 | 155 | extern int mpc_1(); 156 | extern int mpc_2(); 157 | extern int mpc_3(); 158 | extern int mpc_4(); 159 | extern int mpc_5(); 160 | extern int mpc_6(); 161 | 162 | extern int bind_1(); 163 | extern int bind_2(); 164 | extern int bind_4(); 165 | extern int bind_5(); 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /src/raw_pointer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__raw_pointer__h 2 | #define h__raw_pointer__h 3 | 4 | template struct raw_pointer { 5 | 6 | }; 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/rpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ksh 2 | cmd="../bin/main $*" 3 | echo $cmd 4 | eval $cmd 5 | -------------------------------------------------------------------------------- /src/show.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__show__h 2 | #define h__show__h 3 | 4 | 5 | template 6 | struct args_printer 7 | { 8 | static std::ostream& pp(std::ostream& strm) { 9 | strm << typeid(Arg0).name() << ","; 10 | args_printer::pp(strm); 11 | return strm; 12 | } 13 | 14 | }; 15 | 16 | template 17 | struct args_printer<1, Arg0> 18 | { 19 | static std::ostream& pp(std::ostream& strm) { 20 | strm << typeid(Arg0).name(); 21 | return strm; 22 | } 23 | }; 24 | 25 | template 26 | std::ostream& typeids(std::ostream& strm) { 27 | args_printer::pp(strm); 28 | return strm; 29 | } 30 | 31 | template 32 | std::ostream& operator<<(std::ostream& strm, const std::forward_list& L) 33 | { 34 | strm << "std::forward_list<" << typeid(T).name() << "> ["; 35 | size_t index = 7; 36 | for (auto& v : L) { 37 | strm << v << ","; 38 | if (index % 10 == 0) { 39 | strm<< std::endl; 40 | } 41 | } 42 | return strm << "]"; 43 | } 44 | 45 | template 46 | std::ostream& operator<<(std::ostream& strm, const std::list& L) 47 | { 48 | strm << "std::list<" << typeid(T).name() << "> ["; 49 | size_t index = 7; 50 | for (auto& v : L) { 51 | strm << v << ","; 52 | if (index % 10 == 0) { 53 | strm<< std::endl; 54 | } 55 | } 56 | return strm << "]"; 57 | } 58 | template 59 | std::ostream& operator<<(std::ostream& strm, const std::pair& p) 60 | { 61 | return strm << "(" << p.first << "," << p.second << ")"; 62 | } 63 | 64 | //from Josuttis : The c++ standard library 2nd edition 65 | 66 | template 67 | struct print_tuple { 68 | static std::ostream& pp(std::ostream& strm, const std::tuple& t) { 69 | strm << std::get(t) << ((i+1 == MAX) ? "" : ","); 70 | return print_tuple::pp(strm,t); 71 | } 72 | }; 73 | template 74 | struct print_tuple { 75 | static std::ostream& pp(std::ostream& strm, const std::tuple& t) { 76 | return strm; 77 | } 78 | }; 79 | template 80 | std::ostream& operator<<(std::ostream& strm, const std::tuple& t) { 81 | strm << "("; 82 | print_tuple<0, sizeof...(args), args...>::pp(strm,t); 83 | return strm<<")"; 84 | } 85 | 86 | template 87 | std::ostream& operator<<(std::ostream& strm, std::shared_ptr t) 88 | { 89 | strm << "std::shared_ptr<" << typeid(T).name() << ">("; 90 | if (t) { 91 | return strm << *t << ")"; 92 | } 93 | return strm << "NULL)"; 94 | } 95 | 96 | template 97 | std::ostream& operator<<(std::ostream& strm, std::function F) 98 | { 99 | strm << "std::function<" 100 | << typeid(Ret).name() 101 | << "(" ; 102 | typeids(strm); 103 | strm << ")>"; 104 | return strm; 105 | } 106 | 107 | 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/snippets.txt: -------------------------------------------------------------------------------- 1 | #if 0 2 | struct do_helper_alt { 3 | /* 4 | attempt at generalization..... 5 | template 6 | static auto dofor(std::forward_list L1, std::forward_list L2, std::forward_list L3, std::forward_list... L) { 7 | return [=](lambda f) { 8 | auto cff = curry(f); 9 | return _dofor_(L1,L2,L3)(cff); 10 | }; 11 | }; 12 | 13 | template 14 | static auto _dofor_(std::forward_list L1, std::forward_list L2, std::forward_list L3, std::forward_list... L) { 15 | return [=] (lambda cff) { 16 | auto C = _dofor_(L2, L3, L...)(cff);<==== note difference; does this cause reverse of order ?? 17 | typedef decltype(cff(T1())(T2())(T3())) ret_t;====> needs recursive declaration... 18 | auto K = applicative_functor::apply(C)(L1);<<==order is reversed ?? 19 | return K; 20 | }; 21 | }; 22 | */ 23 | 24 | /////////////////////////////////////////////////////////////////////////////////////// 25 | // template 26 | // static auto dofor(std::forward_list L1, std::forward_list L2, std::forward_list L3) { 27 | // return [=](lambda f) { 28 | // auto cff = curry(f); 29 | // return _dofor_(L1,L2,L3)(cff); 30 | // }; 31 | // }; 32 | 33 | template 34 | static auto dofor(std::forward_list... L) { 35 | return [=](lambda f) { 36 | auto cff = curry(f); 37 | return _dofor_(L...)(cff); 38 | }; 39 | }; 40 | 41 | 42 | template 43 | static auto _dofor_(std::forward_list L1, std::forward_list L2, std::forward_list L3, std::forward_list... L) { 44 | return [=] (lambda cff) { 45 | auto C = _dofor_(L1, L2)(cff); 46 | typedef decltype(cff(T1())(T2())(T3())) ret_t; 47 | auto K = applicative_functor::apply(C)(L3); 48 | return K; 49 | }; 50 | }; 51 | 52 | template 53 | static auto _dofor_(std::forward_list L1, std::forward_list L2) { 54 | return [=] (lambda cff) { 55 | auto C = _dofor_(L1)(cff); 56 | typedef decltype(cff(T1())(T2())) ret_t; 57 | auto J = applicative_functor::apply(C)(L2); 58 | return J; 59 | }; 60 | }; 61 | 62 | template 63 | static auto _dofor_(std::forward_list L) { 64 | return [=] (lambda cff) -> std::forward_list { 65 | typedef decltype(cff(T1())) ret_t; 66 | auto cffl = applicative_functor::pure(cff); 67 | auto C = applicative_functor::apply(cffl)(L); 68 | return C; 69 | }; 70 | }; 71 | 72 | }; 73 | #endif 74 | 75 | 76 | template 77 | struct b0 { 78 | typedef lambda ret_t; 79 | }; 80 | 81 | template 82 | struct type_list { 83 | typedef typename std::tuple type; 84 | }; 85 | 86 | template 87 | struct type_element { 88 | typedef typename std::tuple_element>::type type; 89 | }; 90 | 91 | struct print_helper { 92 | template 93 | static void pp(std::forward_list L0, std::forward_list... L) { 94 | std::cout << L0 << std::endl; 95 | pp(L...); 96 | } 97 | template 98 | static void pp(std::forward_list L0) { 99 | std::cout << L0 << std::endl; 100 | } 101 | }; 102 | 103 | 104 | // template 105 | // struct testy { 106 | // //static const int index = testy::index + 1; 107 | // //static int get_index (int l) { 108 | // // if (l == index) return index; 109 | // // return testy::get_index(l); 110 | // //} 111 | // static void dothis(std::forward_list L1, args... A) { 112 | // std::cout << L1 << std::endl; 113 | // return testy::dothis(A...); 114 | // } 115 | // }; 116 | 117 | // template 118 | // struct testy { 119 | // //static const int index = 0; 120 | // //static int get_index(int l) { 121 | // // return index; 122 | // //} 123 | // static void dothis(std::forward_list L) { 124 | // std::cout << L << std::endl; 125 | // } 126 | 127 | //}; 128 | int do_7 () 129 | { 130 | type_list::type t = std::make_tuple(10, '1', "hello"); 131 | type_element<0, int,char, std::string>::type AAA; 132 | AAA = 1; 133 | std::cout << AAA << std::endl; 134 | 135 | std::forward_list< type_element<0, int,char, std::string>::type> LL0; 136 | std::forward_list::type> LL1; 137 | std::forward_list::type> LL2; 138 | 139 | std::cout << LL0 << std::endl; 140 | std::cout << LL1 << std::endl; 141 | std::cout << LL2 << std::endl; 142 | 143 | print_helper::pp(LL0,LL1,LL2); 144 | 145 | 146 | //------------------------------------------------------ 147 | 148 | //template 149 | //std::function (T)> curry (F op) 150 | //{ 151 | // return [=] (T x) { return [=] (U y) {return op(x, y);};}; 152 | //} 153 | //typename curry_helper::f1_t 154 | -------------------------------------------------------------------------------- /src/state.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "state.hpp" 4 | 5 | typedef state_computation> stack_comp; 6 | typedef std::list istack; 7 | 8 | int st_0() 9 | { 10 | istack L = {1,2,3,4}; 11 | 12 | stack_comp pop = [] (istack s) { 13 | auto val = s.front(); 14 | s.pop_front(); 15 | return state_tuple(val, s); 16 | }; 17 | 18 | state SM(pop); 19 | std::cerr << SM << std::endl; 20 | auto R = runState(SM, L); 21 | std::cerr << R << std::endl; 22 | 23 | std::function push = [](int val) { 24 | return [val] (istack s) { 25 | s.push_front(val); 26 | return state_tuple(s); 27 | }; 28 | }; 29 | 30 | state SP(push(4987678)); 31 | std::cerr << SP << std::endl; 32 | auto S = runState(SP, L); 33 | std::cerr << S << std::endl; 34 | 35 | return 0; 36 | } 37 | 38 | int st_1() 39 | { 40 | std::default_random_engine de; 41 | 42 | std::uniform_int_distribution di(10, 20); 43 | std::cerr << di << std::endl; 44 | 45 | state_computation> getrand = [&de] (std::uniform_int_distribution s) { 46 | auto val = s(de); 47 | return state_tuple >(val, s); 48 | }; 49 | 50 | state > ST(getrand); 51 | int n = 10; 52 | auto S = runState(ST, di); 53 | std::cerr << "iter : " << n << " " << S << std::endl;; 54 | while ( n-- > 0) { 55 | S = runState(ST, S.state().first); 56 | std::cerr << "iter : " << n << " " << S << std::endl;; 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/state.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__state__h 2 | #define h__state__h 3 | // 4 | //variation on a pair which allows the first element not to be set. 5 | // 6 | template 7 | struct state_tuple { 8 | explicit state_tuple (S s) : e(std::make_pair(A(), s)), set(false){} 9 | state_tuple (A a, S s) : e(std::make_pair(a,s)), set(true) {} 10 | state_tuple(const state_tuple& s) : e(s.e), set(s.set){} 11 | std::ostream& pp(std::ostream& strm) const { 12 | if (set) { 13 | strm << e; 14 | } 15 | else { 16 | strm << "(()," << e.second << ")"; 17 | } 18 | return strm; 19 | } 20 | 21 | std::pair value() const { 22 | return std::make_pair(e.first, set); 23 | } 24 | 25 | std::pair state() const { 26 | return std::make_pair(e.second, true); 27 | } 28 | 29 | private : 30 | std::pair e; 31 | bool set; 32 | }; 33 | 34 | template 35 | using state_computation = std::function< state_tuple (S)>; 36 | 37 | template 38 | struct state 39 | { 40 | explicit state(state_computation C) : C(C){} 41 | state(const state& o) : C(o.C){} 42 | state& operator= (const state& o) { 43 | if (&o == this) { 44 | return *this; 45 | } 46 | C = o.C; 47 | return *this; 48 | } 49 | std::ostream& pp(std::ostream& strm) const { 50 | strm << "[state < " << typeid(A).name() << "," << typeid(S).name() << "]"; 51 | return strm; 52 | } 53 | 54 | state_tuple run_state(S state) { 55 | return C(state); 56 | } 57 | 58 | private: 59 | state_computation C; 60 | }; 61 | 62 | template 63 | std::ostream& operator<<(std::ostream& strm, const state& M) 64 | { 65 | M.pp(strm); 66 | return strm; 67 | 68 | } 69 | 70 | template 71 | std::ostream& operator<<(std::ostream& strm, const state_tuple& ST) 72 | { 73 | ST.pp(strm); 74 | return strm; 75 | 76 | } 77 | 78 | template 79 | state_tuple runState(state M, S state) 80 | { 81 | return M.run_state(state); 82 | } 83 | 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/state_monad.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "functor.hpp" 4 | #include "applicative_functor.hpp" 5 | #include "state.hpp" 6 | #include "monad.hpp" 7 | #include "state_monad.hpp" 8 | 9 | 10 | ////////////////////////////// 11 | typedef state_computation> stack_comp; 12 | typedef std::list istack; 13 | 14 | int stm_0() 15 | { 16 | std::default_random_engine de; 17 | std::uniform_int_distribution di(10, 20); 18 | state_computation> getrand = [&de] (std::uniform_int_distribution s) { 19 | auto val = s(de); 20 | return state_tuple >(val, s); 21 | }; 22 | 23 | state > ST(getrand); 24 | 25 | std::function f = [] (int i) { 26 | if (i < 15) { 27 | return 'A'; 28 | } 29 | return 'Z'; 30 | }; 31 | 32 | 33 | int n = 10; 34 | while (n-- > 0) { 35 | auto SRT = functor::fmap(f, ST); 36 | auto S = runState(SRT, di); 37 | std::cerr << S << std::endl;; 38 | } 39 | 40 | //auto SRT = functor::fmap>(f)(ST); 41 | auto SRT = functor::fmap>(f, ST); 42 | auto S = runState(SRT, di); 43 | std::cerr << S << std::endl;; 44 | 45 | return 0; 46 | } 47 | 48 | 49 | 50 | int stm_1() 51 | { 52 | istack L = {1,2,3,4}; 53 | 54 | std::function f = [] (int i) { 55 | if (i < 3) { 56 | return 'A'; 57 | } 58 | return 'Z'; 59 | }; 60 | 61 | 62 | stack_comp pop = [] (istack s) { 63 | auto val = s.front(); 64 | s.pop_front(); 65 | return state_tuple(val, s); 66 | }; 67 | 68 | state SM(pop); 69 | std::cerr << SM << std::endl; 70 | state SMT = functor::fmap(f, SM); 71 | std::cerr << SMT << std::endl; 72 | 73 | auto R = runState(SMT, L); 74 | std::cerr << R << std::endl; 75 | 76 | 77 | std::function push = [](int val) { 78 | return [val] (istack s) { 79 | s.push_front(val); 80 | return state_tuple(s); 81 | }; 82 | }; 83 | 84 | state SP(push(498)); 85 | std::cerr << SP << std::endl; 86 | auto S = runState(SP, L); 87 | std::cerr << S << std::endl; 88 | 89 | state SPT = functor::fmap(f, SP); 90 | auto st = runState(SPT, L); 91 | std::cerr << st << std::endl; 92 | 93 | return 0; 94 | } 95 | 96 | int stm_2() 97 | { 98 | istack L = {1,2,3,4}; 99 | 100 | auto ST = applicative_functor::pure(5); 101 | std::cerr << ST << std::endl; 102 | 103 | auto S = runState(ST, L); 104 | std::cerr << S << std::endl;; 105 | 106 | return 0; 107 | } 108 | 109 | 110 | int stm_3() 111 | { 112 | istack L = {1,2,3,4}; 113 | 114 | std::function f = [] (int i) { 115 | if (i < 3) { 116 | return 'A'; 117 | } 118 | return 'Z'; 119 | }; 120 | 121 | stack_comp pop = [] (istack s) { 122 | auto val = s.front(); 123 | s.pop_front(); 124 | return state_tuple(val, s); 125 | }; 126 | 127 | state SM(pop); 128 | 129 | auto F = applicative_functor::pure(f); 130 | std::cerr << F << std::endl; 131 | 132 | auto r1 = runState(SM, L); 133 | std::cerr << r1 << std::endl;; 134 | auto SC = applicative_functor::apply(F, SM); 135 | auto r2 = runState(SC, L); 136 | std::cerr << r2 << std::endl;; 137 | 138 | return 0; 139 | } 140 | 141 | 142 | int stm_4() 143 | { 144 | istack L = {1,2,3,4}; 145 | 146 | 147 | std::function< state (int)> f = [] (int v) { 148 | 149 | std::function push = [](int val) { 150 | return [val] (istack s) { 151 | s.push_front(val); 152 | return state_tuple(s); 153 | }; 154 | }; 155 | 156 | stack_comp pop = [] (istack s) { 157 | auto val = s.front(); 158 | s.pop_front(); 159 | return state_tuple(val, s); 160 | }; 161 | 162 | std::cerr << "v : " << v << std::endl; 163 | if (v > 3) { 164 | state SP(push(v)); 165 | return SP; 166 | } 167 | 168 | state SP(pop); 169 | return SP; 170 | }; 171 | 172 | stack_comp pop = [] (istack s) { 173 | auto val = s.front(); 174 | s.pop_front(); 175 | return state_tuple(val, s); 176 | }; 177 | 178 | state SM(pop); 179 | 180 | 181 | auto R = monad::bind(SM, f); 182 | std::cerr << R << std::endl; 183 | 184 | auto r0 = runState(SM, istack{1,4,5,3,1,8}); 185 | std::cerr << r0 << std::endl; 186 | 187 | auto r1 = runState(R, istack{1,4,5,3,1,8}); 188 | std::cerr << r1 << std::endl; 189 | 190 | return 0; 191 | } 192 | 193 | int stm_5() 194 | { 195 | istack L = {1,2,3,4}; 196 | 197 | std::function pop = []() { 198 | return [] (istack s) { 199 | auto val = s.front(); 200 | s.pop_front(); 201 | return state_tuple(val, s); 202 | }; 203 | }; 204 | 205 | std::function push = [](int val) { 206 | return [val] (istack s) { 207 | s.push_front(val); 208 | return state_tuple(s); 209 | }; 210 | }; 211 | 212 | std::function< state (int)> f = [pop] (int v) { 213 | state SP(pop()); 214 | return SP; 215 | }; 216 | 217 | std::function< state (int)> g = [push] (int v) { 218 | state SP(push(498)); 219 | return SP; 220 | }; 221 | 222 | state SP(pop()); 223 | auto r1 = runState(SP,L); 224 | std::cerr << r1 << std::endl; 225 | 226 | state R = monad::bind(SP, f); 227 | auto res = runState(R,L); 228 | std::cerr << res << std::endl; 229 | 230 | state R2 = monad::bind(R, g); 231 | auto res2 = runState(R2,L); 232 | std::cerr << res2 << std::endl; 233 | auto res21 = runState(R2,L); 234 | std::cerr << res21 << std::endl; 235 | 236 | state R3 = monad::bind(R2, g); 237 | auto res3 = runState(R3,L); 238 | std::cerr << "res3 " << res3 << std::endl; 239 | auto res31 = runState(R3,L); 240 | std::cerr << "res31 " << res3 << std::endl; 241 | int n = 10; 242 | while (n--) { 243 | state R4 = monad::bind(R3, g); 244 | auto res4 = runState(R4,L); 245 | std::cerr << "res4 :" << res4 << std::endl; 246 | } 247 | return 0; 248 | } 249 | // 250 | // state monad 251 | // monad law : [return a >>= k = k] 252 | // 253 | int stm_6() 254 | { 255 | istack L = {1,2,3,4}; 256 | 257 | std::function push = [](int val) { 258 | return [val] (istack s) { 259 | s.push_front(val); 260 | return state_tuple(s); 261 | }; 262 | }; 263 | 264 | std::function< state (int)> g = [push] (int v) { 265 | state SP(push(498)); 266 | return SP; 267 | }; 268 | 269 | int a = 897; 270 | state R = monad::mreturn(a); 271 | state R1 = monad::bind(R, g); 272 | auto res = runState(R1,L); 273 | std::cerr << res << std::endl; 274 | 275 | state R2 = g(a); 276 | auto res2 = runState(R2,L); 277 | std::cerr << res2 << std::endl; 278 | 279 | 280 | std::function pop = []() { 281 | return [] (istack s) { 282 | auto val = s.front(); 283 | s.pop_front(); 284 | return state_tuple(val, s); 285 | }; 286 | }; 287 | std::function< state (int)> f = [pop] (int v) { 288 | state SP(pop()); 289 | return SP; 290 | }; 291 | 292 | state RP = monad::mreturn(a); 293 | state R12 = monad::bind(RP, f); 294 | auto res12 = runState(R12,L); 295 | std::cerr << res12 << std::endl; 296 | 297 | state R22 = f(a); 298 | auto res22 = runState(R22,L); 299 | std::cerr << res22 << std::endl; 300 | 301 | return 0; 302 | } 303 | 304 | int stm_7() 305 | { 306 | istack L = {1,2,3,4}; 307 | 308 | std::function pop = []() { 309 | return [] (istack s) { 310 | auto val = s.front(); 311 | s.pop_front(); 312 | return state_tuple(val, s); 313 | }; 314 | }; 315 | 316 | std::function push = [](int val) { 317 | return [val] (istack s) { 318 | s.push_front(val); 319 | return state_tuple(s); 320 | }; 321 | }; 322 | 323 | std::function< state (int)> f = [pop] (int v) { 324 | state SP(pop()); 325 | return SP; 326 | }; 327 | 328 | 329 | std::function< state (int)> g1 = [push] (int v) { 330 | state SP(push(498)); 331 | return SP; 332 | }; 333 | 334 | std::function (int)>(int)> g = [push] (int val) { 335 | std::function< state (int)> gf = [val, push] (int v) { 336 | state SP(push(val)); 337 | return SP; 338 | }; 339 | return gf; 340 | }; 341 | 342 | state SP(pop()); 343 | auto r1 = runState(SP,L); 344 | int a = r1.value().first; 345 | 346 | state R = monad::bind(SP, f); 347 | auto r2 = runState(R,L); 348 | int b = r2.value().first; 349 | 350 | std::function< state (int)> lam1 = g(a); 351 | state R2 = monad::bind(R, lam1); 352 | std::function< state (int)> lam2 = g(b); 353 | state R3 = monad::bind(R2, lam2); 354 | auto res3 = runState(R3,L); 355 | std::cerr << res3 << std::endl; 356 | 357 | return 0; 358 | } 359 | 360 | // 361 | // 362 | // monad law : [m >>= (\x->k x >>= h) = (m >>= k) >>= h] 363 | // 364 | // 365 | 366 | int stm_8() 367 | { 368 | istack L = {1,2,3,4}; 369 | 370 | std::function pop = []() { 371 | return [] (istack s) { 372 | auto val = s.front(); 373 | s.pop_front(); 374 | return state_tuple(val, s); 375 | }; 376 | }; 377 | 378 | std::function push = [](int val) { 379 | return [val] (istack s) { 380 | s.push_front(val); 381 | return state_tuple(s); 382 | }; 383 | }; 384 | 385 | std::function< state (int)> k = [pop] (int v) { 386 | state SP(pop()); 387 | return SP; 388 | }; 389 | 390 | 391 | std::function< state (int)> h= [push] (int v) { 392 | state SP(push(498)); 393 | return SP; 394 | }; 395 | 396 | std::function< state (int)> lambda = [&h,&k] (int v) { 397 | auto sp = new state(k(v)); 398 | state& KX = *sp; 399 | return monad::bind(KX, h); 400 | }; 401 | 402 | state M(pop()); 403 | state LE = monad::bind(M, lambda); 404 | auto lhs = runState(LE,L); 405 | std::cerr << lhs << std::endl; 406 | 407 | state R = monad::bind(M, k); 408 | state R2 = monad::bind(R, h); 409 | auto rhs = runState(R2,L); 410 | std::cerr << rhs << std::endl; 411 | 412 | return 0; 413 | } 414 | 415 | 416 | int stm_9() 417 | { 418 | typedef std::uniform_int_distribution idist; 419 | std::default_random_engine de; 420 | 421 | 422 | state_computation> getrand = [&de] (std::uniform_int_distribution s) { 423 | auto val = s(de); 424 | return state_tuple >(val, s); 425 | }; 426 | 427 | state ST(getrand); 428 | 429 | std::function(int)> f = [&de, &ST](int val) { 430 | std::cerr << val <::bind(ST,f); 435 | auto S2 = monad::bind(S1,f); 436 | auto S3 = monad::bind(S2,f); 437 | auto S4 = monad::bind(S3,f); 438 | auto S5 = monad::bind(S4,f); 439 | auto S6 = monad::bind(S5,f); 440 | auto S7 = monad::bind(S6,f); 441 | auto S8 = monad::bind(S7,f); 442 | auto Sf = monad::bind(S8,f); 443 | 444 | auto S = runState(Sf, idist (10, 20)); 445 | std::cerr << S << std::endl;; 446 | S = runState(Sf, idist (100, 200)); 447 | std::cerr << S << std::endl;; 448 | 449 | return 0; 450 | } 451 | 452 | int stm_10() 453 | { 454 | typedef std::list icont_t; 455 | typedef std::uniform_int_distribution idist_t; 456 | typedef std::pair state_t; 457 | typedef state_tuple state_tuple_t; 458 | 459 | std::default_random_engine de((unsigned int)time(0)); 460 | 461 | state_computation getrand = [&de] (state_t s) { 462 | auto val = s.second(de); 463 | s.first.push_back(val); 464 | return state_tuple_t(val, s); 465 | }; 466 | 467 | std::function (int, int)> getrand2 = [&de](int f, int t) { 468 | return [&de,f,t] (state_t s) { 469 | auto val = s.second(de); 470 | return state_tuple_t(val, std::make_pair(s.first, idist_t(f,t))); 471 | }; 472 | }; 473 | 474 | 475 | state ST(getrand); 476 | 477 | std::function(int)> f = [&ST,&getrand2](int val) { 478 | std::cerr << val < (getrand2(10000,11456)); 481 | } 482 | return ST; 483 | }; 484 | 485 | auto S1 = monad::bind(ST,f); 486 | auto S2 = monad::bind(S1,f); 487 | auto S3 = monad::bind(S2,f); 488 | auto S4 = monad::bind(S3,f); 489 | auto S5 = monad::bind(S4,f); 490 | auto S6 = monad::bind(S5,f); 491 | auto S7 = monad::bind(S6,f); 492 | auto S8 = monad::bind(S7,f); 493 | auto S9 = monad::bind(S8,f); 494 | auto S10 = monad::bind(S9,f); 495 | auto S11 = monad::bind(S10,f); 496 | auto S12 = monad::bind(S11,f); 497 | auto Sf = monad::bind(S12,f); 498 | 499 | auto S = runState(Sf, std::make_pair(icont_t(), idist_t(10,20))); 500 | std::cerr << S << std::endl;; 501 | S = runState(Sf, std::make_pair(icont_t(), idist_t(100,200))); 502 | std::cerr << S << std::endl;; 503 | 504 | return 0; 505 | } 506 | 507 | 508 | 509 | -------------------------------------------------------------------------------- /src/state_monad.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__state_monad_h 2 | #define h_state_monad__h 3 | #include "state.hpp" 4 | 5 | 6 | template <> 7 | struct functor { 8 | 9 | template 10 | static state fmap (std::function f, state M) { 11 | state_computation comp =[f,&M](S s) { 12 | auto next = runState(M, s); 13 | auto value = next.value(); 14 | auto new_state = next.state().first; 15 | if (value.second) { 16 | return state_tuple(f(value.first), new_state); 17 | } 18 | return state_tuple(new_state); 19 | }; 20 | state ST(comp); 21 | return ST; 22 | } 23 | 24 | template 25 | static auto fmap (lambda F, state M) -> state { 26 | state_computation comp =[F,&M](S s) { 27 | auto next = runState(M, s); 28 | auto value = next.value(); 29 | auto new_state = next.state().first; 30 | if (value.second) { 31 | return state_tuple(F(value.first), new_state); 32 | } 33 | return state_tuple(new_state); 34 | }; 35 | state ST(comp); 36 | return ST; 37 | } 38 | 39 | 40 | // this doesn't work (yet) 41 | template 42 | static std::function(state)> fmap (std::function f) { 43 | return [&f] (state M) { 44 | /* 45 | state_computation comp =[f,&M](S s) { 46 | auto next = runState(M, s); 47 | auto value = next.value(); 48 | auto new_state = next.state().first; 49 | if (value.second) { 50 | return state_tuple(f(value.first), new_state); 51 | } 52 | return state_tuple(new_state); 53 | }; 54 | state ST(comp); 55 | return ST; 56 | */ 57 | return fmap(f, M); 58 | }; 59 | } 60 | 61 | }; 62 | template <> 63 | struct applicative_functor : public functor 64 | { 65 | 66 | template static state pure(A val) { 67 | state_computation comp =[val](S s) { 68 | return state_tuple(val, s); 69 | }; 70 | state ST(comp); 71 | return ST; 72 | } 73 | 74 | template 75 | static state apply ( state, S> F, state M) { 76 | 77 | state_computation comp =[F,&M](S s) { 78 | auto rs1 = runState(F, s); 79 | auto resv = rs1.value(); 80 | if (resv.second) { 81 | std::function f = resv.first; 82 | auto MT = functor::fmap(f, M); 83 | auto rs2 = runState(MT, s); 84 | auto value = rs2.value(); 85 | auto new_state = rs2.state().first; 86 | if (value.second) { 87 | return state_tuple(value.first, new_state); 88 | } 89 | return state_tuple(new_state); 90 | } 91 | return state_tuple(s); 92 | }; 93 | state ST(comp); 94 | return ST; 95 | } 96 | 97 | }; 98 | 99 | template<> struct monad : public applicative_functor { 100 | 101 | template 102 | static state bind(state& M, std::function< state (A)>& f) { 103 | state_computation comp =[&f,&M](S s) { 104 | auto res = runState(M, s); 105 | state state_g = f (res.value().first); 106 | return runState(state_g, res.state().first); 107 | }; 108 | return state (comp); 109 | }; 110 | 111 | template static state mreturn (A val) { 112 | return applicative_functor::pure(val); 113 | } 114 | 115 | }; 116 | 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /src/thunk.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "show.hpp" 3 | #include "thunk.hpp" 4 | 5 | 6 | ////////////////////////////// 7 | 8 | 9 | 10 | int th_0() 11 | { 12 | std::function f = [](int x) { return 34*x - x;}; 13 | 14 | auto th = thunk(f, 2); 15 | std::cerr << "thunk : " << th << " => " << th() << std::endl; 16 | 17 | //exec_pack(f, n); 18 | //auto nm = value_pack(1,2,3); 19 | //std::cerr << nm.val << "," << nm.rest.val << "," << nm.rest.rest.val << std::endl; 20 | 21 | auto thh = thunk(f,1); 22 | std::cerr << thh << " ==> " << thh() << std::endl; 23 | 24 | std::function f2 = [](int x, int y) { return 34*x - y;}; 25 | auto th2 = thunk(f2,1,4); 26 | std::cerr << th2 << " ==> " << th2() << std::endl; 27 | 28 | std::function f3 = [](int x, int y, float z) { return 34*x - y*z;}; 29 | auto th3 = thunk(f3,1,4,0.989667); 30 | std::cerr << th3 << " ==> " << th3() << std::endl; 31 | 32 | std::function f0 = []() { return 34;}; 33 | //auto th0 = thunk_helper(f0); 34 | //std::cerr << th0 << " ==> " << th0() << std::endl; 35 | 36 | 37 | return 0; 38 | } 39 | 40 | int th_1() 41 | { 42 | std::function f = [](int x, int y) { return 34*x - x*y;}; 43 | 44 | auto th = thunk(f, 2, 56); 45 | std::cerr << "thunk : " << th << " => " << th() << std::endl; 46 | 47 | return 0; 48 | } 49 | 50 | int th_2() 51 | { 52 | std::function f = [](std::string s, int x, int y, float f) { return 34*x - x*y;}; 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /src/thunk.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__thunk__h 2 | #define h__thunk__h 3 | #include "value_pack.hpp" 4 | 5 | /* 6 | this is a workaround a bug in gcc which doesn't allow parameter packs to be expanded inside lambda functions. 7 | 8 | */ 9 | #if 0 10 | template 11 | struct thunk_helper 12 | { 13 | 14 | 15 | }; 16 | 17 | template 18 | struct thunk_helper<1, R, Arg1> 19 | { 20 | typedef std::function function_type; 21 | 22 | explicit thunk_helper(function_type F, Arg1 arg1) : func(F), val1(arg1){} 23 | thunk_helper(const thunk_helper& o) : func(o.func), val1(o.val1) {} 24 | void operator=(const thunk_helper&) = delete; 25 | R operator()() { 26 | return func(val1); 27 | } 28 | 29 | std::ostream& pp(std::ostream& strm) const { 30 | strm << "thunk <" << 1 31 | << "," << typeid(R).name() 32 | << "," << typeid(Arg1).name() 33 | << ">" 34 | << "[ " << func << "(" << val1 << ")]"; 35 | return strm; 36 | } 37 | 38 | private: 39 | std::function func; 40 | const Arg1 val1; 41 | }; 42 | 43 | template 44 | struct thunk_helper<2, R, Arg1, Arg2> 45 | { 46 | typedef std::function function_type; 47 | 48 | explicit thunk_helper(function_type F, Arg1 arg1, Arg2 arg2) : func(F), val1(arg1), val2(arg2){} 49 | thunk_helper(const thunk_helper& o) : func(o.func), val1(o.val1), val2(o.val2) {} 50 | void operator=(const thunk_helper&) = delete; 51 | R operator()() { 52 | return func(val1, val2); 53 | } 54 | 55 | std::ostream& pp(std::ostream& strm) const { 56 | strm << "thunk <" << 2 57 | << ","<< typeid(R).name() 58 | << "," << typeid(Arg1).name() 59 | << "," << typeid(Arg2).name() 60 | << ">" 61 | << "[ " << func << "(" << val1 << "," << val2 << ")]"; 62 | return strm; 63 | } 64 | 65 | 66 | private: 67 | std::function func; 68 | const Arg1 val1; 69 | const Arg2 val2; 70 | }; 71 | #endif 72 | 73 | 74 | template 75 | struct thunk_helper 76 | { 77 | typedef std::function function_type; 78 | 79 | explicit thunk_helper(function_type F, Arg... args) : func(F), val1(args...) {} 80 | thunk_helper(const thunk_helper& o) : func(o.func) , val1(o.val1) {} 81 | 82 | void operator=(const thunk_helper&) = delete; 83 | Ret operator()() { 84 | return apply_pack::apply(func, val1); 85 | } 86 | 87 | std::ostream& pp(std::ostream& strm) const { 88 | 89 | strm << "thunk <" << 1 90 | << "," << typeid(Ret).name() 91 | << "," ; 92 | typeids(strm); 93 | strm << ">"; 94 | strm << "[ " << func << "("; 95 | val1.pp(strm); 96 | strm << ")]"; 97 | return strm; 98 | } 99 | 100 | private: 101 | std::function func; 102 | value_pack val1; 103 | }; 104 | 105 | 106 | template 107 | std::ostream& operator<<(std::ostream& strm, thunk_helper& th) 108 | { 109 | th.pp(strm); 110 | return strm; 111 | } 112 | 113 | 114 | template 115 | thunk_helper thunk (std::function F, Args... args) 116 | { 117 | return thunk_helper(F, args...); 118 | }; 119 | 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/trans.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "map.hpp" 3 | #include "zip.hpp" 4 | #include "show.hpp" 5 | 6 | static char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 7 | 8 | static char irc (int i) 9 | { 10 | return digits[ abs(i) % 10 ]; 11 | } 12 | 13 | int trans_1() 14 | { 15 | std::forward_list L = {1,2,3,4,5,67,12}; 16 | auto v = irc (2345); 17 | std::cout << " v : " << v << std::endl; 18 | 19 | std::function op = [] (std::string& a, int v) { a.append(1, irc(v)); return a;}; 20 | 21 | auto op2 = [] (std::string& a, int v) { a.append(1, irc(v)); return a;}; 22 | 23 | std::string res = std::accumulate(L.begin(), L.end(), std::string(""), op2); 24 | std::cout << " res : " << res << std::endl; 25 | return 0; 26 | } 27 | 28 | int trans_2() 29 | { 30 | 31 | std::forward_list L = {1,-6,23,78,45,13}; 32 | auto max = [] (int x, int y) { return (x > y) ? x : y;}; 33 | auto res = std::accumulate(L.begin(), L.end(), std::numeric_limits::min(), max); 34 | std::cout << "maximum : " << res << std::endl; 35 | return 0; 36 | } 37 | 38 | int trans_3() 39 | { 40 | auto show = [] (int v) { std::cout << v << ","; return v;}; 41 | typedef std::list list_t; 42 | list_t L = {1,-6,23,78,45,13}; 43 | auto m = [] (list_t L, int y) { L.push_back( 2*y + 1); return L;}; 44 | auto res = std::accumulate(L.begin(), L.end(), list_t(), m); 45 | map(show,res); 46 | return 0; 47 | } 48 | 49 | int trans_4() 50 | { 51 | typedef std::forward_list list_t; 52 | list_t L = {1,-6,23,78,45,13}; 53 | auto op = [] (int y) {return list_t({2*y+1});}; 54 | auto concat = [] (list_t A, list_t B) { A.splice_after(A.before_begin(), B); return A;}; 55 | auto bind = std::bind(concat, std::placeholders::_1, std::bind(op, std::placeholders::_2)); 56 | auto show = [] (int v) { std::cout << v << ","; return v;}; 57 | auto res = std::accumulate(L.begin(), L.end(), list_t(), bind); 58 | map(show, res); 59 | return 0; 60 | } 61 | 62 | int trans_5() 63 | { 64 | std::forward_list L = {1,67,89,23,45,1,3,99,-90}; 65 | auto show = [] (int v) { std::cout << v << ","; return v;}; 66 | 67 | auto R1 = map (show, L); 68 | auto R2 = map ([] (int y) {return (y + 79) % 45;}, R1); 69 | map(show, R2); 70 | return 0; 71 | } 72 | 73 | int trans_6() 74 | { 75 | std::forward_list L = {1,67,89,23,45,1,3,99,-90}; 76 | auto show = [] (int v) { std::cout << v << ","; return v;}; 77 | std::function< std::function (int)> op = [] (int x) { 78 | return [=] (int y) { 79 | return 4 * x + y; 80 | }; 81 | }; 82 | std::cout << std::endl << "--------------" << std::endl; 83 | map(show, 84 | map([](std::function f){return f(2);}, 85 | map(op, L))); 86 | return 0; 87 | } 88 | 89 | int trans_7() 90 | { 91 | std::forward_list L = {1,67,89,23,45,1,3,99,-90}; 92 | auto show = [] (int v) { std::cout << v << ","; return v;}; 93 | std::function< std::function (int)> op = [] (int x) { 94 | return [=] (int y) { 95 | return 4 * x + y; 96 | }; 97 | }; 98 | auto l = std::bind([](std::function f){return f(2);}, 99 | std::bind(op, std::placeholders::_1)); 100 | 101 | map(show, map(l, L)); 102 | 103 | return 0; 104 | } 105 | 106 | 107 | int trans_8() 108 | { 109 | std::forward_list L = {1,67,89,23,45,1,3,99,-90}; 110 | std::forward_list R = {'a','b','l','u','t','v','r','6','h'}; 111 | 112 | map ([] (int v) { std::cout << v << ","; return v;}, L); 113 | std::cout << std::endl; 114 | 115 | map ([] (char v) { std::cout << v << ","; return v;}, R); 116 | std::cout << std::endl; 117 | 118 | auto H2 = zip (L, R); 119 | 120 | map([] (std::tuple v) { std::cout << v << ","; return v;},H2); 121 | 122 | std::cout << std::endl; 123 | return 0; 124 | } 125 | 126 | int trans_9() 127 | { 128 | std::forward_list L = {1,67,89,23,45,1,3,99,-90}; 129 | std::forward_list R = {'a','b','l','u','t','v','r','6','h'}; 130 | 131 | map ([] (int v) { std::cout << v << ","; return v;}, L); 132 | std::cout << std::endl; 133 | 134 | map ([] (char v) { std::cout << v << ","; return v;}, R); 135 | std::cout << std::endl; 136 | auto op = [] (int x, char z) { 137 | return std::make_tuple(x,z); 138 | }; 139 | auto res = zipWith(op)(L)(R); 140 | map([] (std::tuple v) { std::cout << v << ","; return v;}, res); 141 | 142 | std::cout << std::endl; 143 | return 0; 144 | } 145 | 146 | -------------------------------------------------------------------------------- /src/unary_op.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __unary_op__ 2 | #define __unary_op__ 3 | 4 | template struct unary_op { 5 | 6 | }; 7 | 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/value_pack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__valaue_pack__h 2 | #define h__valaue_pack__h 3 | 4 | template 5 | struct value_pack{ 6 | explicit value_pack(Arg0 val0, Argn... val) : val(val0), rest(val...) {} 7 | value_pack(const value_pack& o) : val(o.val), rest(o.rest){} 8 | void operator=(const value_pack&) = delete; 9 | 10 | Arg0 val; 11 | value_pack rest; 12 | 13 | std::ostream& pp(std::ostream& strm) const { 14 | strm << "value_pack<"; 15 | typeids(strm); 16 | strm << ">{" ; 17 | return ppp(strm); 18 | } 19 | 20 | std::ostream& ppp(std::ostream& strm) const { 21 | strm << val << ","; 22 | rest.ppp(strm); 23 | return strm; 24 | } 25 | }; 26 | 27 | template 28 | struct value_pack { 29 | explicit value_pack(T val0) : val(val0){} 30 | T val; 31 | 32 | std::ostream& pp(std::ostream& strm) const { 33 | strm << "value_pack<"; 34 | typeids(strm); 35 | strm << ">{" ; 36 | return ppp(strm); 37 | } 38 | 39 | 40 | std::ostream& ppp(std::ostream& strm) const { 41 | strm << val << "}"; 42 | return strm; 43 | } 44 | 45 | }; 46 | 47 | template 48 | std::ostream& operator<<(std::ostream& strm, value_pack& th) 49 | { 50 | th.pp(strm); 51 | return strm; 52 | } 53 | ////////////////// 54 | //...... 55 | template 56 | struct apply_pack 57 | { 58 | //static R apply(std::function F, value_pack args) { 59 | // return R(); 60 | //} 61 | }; 62 | 63 | template 64 | struct apply_pack<0,R,void> 65 | { 66 | static R apply(std::function F) { 67 | return F();; 68 | } 69 | }; 70 | 71 | template 72 | struct apply_pack<1,R,Arg0> 73 | { 74 | static R apply(std::function F, value_pack args) { 75 | 76 | return F(args.val);; 77 | } 78 | }; 79 | 80 | template 81 | struct apply_pack<2,R,Arg0,Arg1> 82 | { 83 | static R apply(std::function F, value_pack args) { 84 | 85 | return F(args.val, args.rest.val);; 86 | } 87 | }; 88 | 89 | template 90 | struct apply_pack<3,R,Arg0,Arg1,Arg2> 91 | { 92 | static R apply(std::function F, value_pack args) { 93 | 94 | return F(args.val, args.rest.val, args.rest.rest.val);; 95 | } 96 | }; 97 | 98 | template 99 | struct apply_pack<4,R,Arg0,Arg1,Arg2,Arg3> 100 | { 101 | static R apply(std::function F, value_pack args) { 102 | 103 | return F(args.val, args.rest.val, args.rest.rest.val, args.rest.rest.rest.val); 104 | } 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/w.cpp: -------------------------------------------------------------------------------- 1 | #include "proto.hpp" 2 | #include "w.hpp" 3 | 4 | 5 | 6 | int w_1() 7 | { 8 | W id(0,""); 9 | W val_1(1256, "hello"); 10 | W val_2(-9088, "goodbye"); 11 | W val_3(786, "haha"); 12 | 13 | if ((id + val_1) == (val_1 + id)) { 14 | std::cout << "have indentity element" << std::endl; 15 | } 16 | 17 | if ((val_3 + (val_2 + val_1)) == ((val_3 + val_2) + val_1)) { 18 | std::cout << "have associativity" << std::endl; 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/w.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__w__h 2 | #define h__w__h 3 | 4 | struct W { 5 | 6 | explicit W(int v, const std::string& s) : v(v), s(s){} 7 | W(const W& o) : v(o.v), s(o.s){} 8 | void operator=(const W& o) = delete; 9 | 10 | int ssn() const { return v;} 11 | std::string name() const {return s;} 12 | std::ostream& pp(std::ostream& os) const { 13 | return os << "name : " << s << " ssn :" << v << " "; 14 | } 15 | private : 16 | int v; 17 | std::string s; 18 | }; 19 | 20 | inline std::ostream& operator<<(std::ostream& os, const W& w) 21 | { 22 | return w.pp(os); 23 | } 24 | 25 | inline W operator+(const W& lhs, const W& rhs) 26 | { 27 | std::string s(lhs.name()); 28 | s.append(rhs.name()); 29 | return W(lhs.ssn() + rhs.ssn(), s); 30 | } 31 | 32 | inline bool operator==(const W& lhs, const W& rhs) 33 | { 34 | return (lhs.ssn() == rhs.ssn()) and (lhs.name() == rhs.name()); 35 | } 36 | 37 | inline bool operator!=(const W& lhs, const W& rhs) 38 | { 39 | return ! (lhs == rhs); 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/zip.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__zipwith__h 2 | #define h__zipwith__h 3 | 4 | template 5 | auto zipWith (F f, const std::forward_list& L, const std::forward_list& R) -> std::forward_list 6 | { 7 | std::forward_list H; 8 | std::transform(L.begin(), L.end(), R.begin(), std::front_inserter(H), f); 9 | H.reverse(); 10 | return H; 11 | } 12 | 13 | template 14 | std::forward_list> zip (const std::forward_list& L, const std::forward_list& M) 15 | { 16 | return zipWith([] (const A& a, const B& b) {return std::make_tuple(a,b);}, L, M); 17 | } 18 | 19 | template 20 | auto zipWith (F f) { 21 | return [f](const std::forward_list& L) { 22 | return [f,L](const std::forward_list& R) -> std::forward_list { 23 | std::forward_list H; 24 | std::transform(L.begin(), L.end(), R.begin(), std::front_inserter(H), f); 25 | H.reverse(); 26 | return H; 27 | }; 28 | }; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/zip_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef h__ziplist__h 2 | #define h__ziplist__h 3 | 4 | template using zip_list = std::list; 5 | 6 | 7 | template <> 8 | struct functor { 9 | 10 | template 11 | static std::function (zip_list)> fmap (std::function f) { 12 | return [f](zip_list L) { 13 | return functor::fmap(f, L); 14 | }; 15 | } 16 | 17 | 18 | template 19 | static std::function (zip_list)> fmap (F f) { 20 | return [f](zip_list L) { 21 | return functor::fmap(f, L); 22 | }; 23 | }; 24 | 25 | }; 26 | 27 | template<> struct 28 | applicative_functor :public functor{ 29 | 30 | template 31 | static zip_list pure(A v) { 32 | return applicative_functor::pure(v); 33 | } 34 | 35 | template 36 | static std::function< zip_list (zip_list)> apply(zip_list> F) { 37 | return [F](zip_list L) { 38 | zip_list acc; 39 | auto it1 = F.begin(); 40 | auto it2 = L.begin(); 41 | while (it1 != F.end() && it2 != L.end()) { 42 | auto func = *it1; 43 | auto arg = *it2; 44 | acc.push_front(func(arg)); 45 | it1++; 46 | it2++; 47 | } 48 | acc.reverse(); 49 | return acc; 50 | }; 51 | }; 52 | 53 | template 54 | static std::function< zip_list (zip_list)> apply(zip_list F) { 55 | return [F](zip_list L) { 56 | zip_list acc; 57 | auto it1 = F.begin(); 58 | auto it2 = L.begin(); 59 | while (it1 != F.end() && it2 != L.end()) { 60 | auto func = *it1; 61 | auto arg = *it2; 62 | acc.push_front(func(arg)); 63 | it1++; 64 | it2++; 65 | } 66 | acc.reverse(); 67 | return acc; 68 | }; 69 | }; 70 | 71 | }; 72 | 73 | #endif 74 | --------------------------------------------------------------------------------