├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── all.pdf ├── base.pdf ├── base.tex ├── common ├── anchor-logo.png └── prelude.tex ├── images ├── foldl.png └── foldr.png ├── lens.pdf └── lens.tex /.gitignore: -------------------------------------------------------------------------------- 1 | _minted-*/ 2 | *.aux 3 | *.log 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2015 Anchor Systems Pty Ltd, Edward Kmett 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following 14 | disclaimer in the documentation and/or other materials provided 15 | with the distribution. 16 | 17 | 3. Neither the name of the project nor the names of its contributors 18 | may be used to endorse or promote products derived from this 19 | software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CHEAT_SHEETS=$(wildcard *.tex) 2 | PDFS=$(CHEAT_SHEETS:tex=pdf) 3 | 4 | all: $(PDFS) 5 | clean: 6 | rm -f $(PDFS) 7 | rm -f *.aux *.log 8 | rm -rf _minted-*/ 9 | 10 | %.pdf: %.tex common/*.tex 11 | pdflatex -shell-escape $< -o $@ 12 | 13 | all.pdf: $(PDFS) 14 | pdfunite $(PDFS) all.pdf 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The most important library documentation, on your desk! 2 | 3 | Looking up documentation can be jarring when you just want to remember a type 4 | signature or how to glue something together. 5 | 6 | Why not have the your most commonly looked up things in one place? Perhaps your 7 | friends will learn some nice tricks, too! 8 | 9 | ## The PDFs: 10 | 11 | Currently all A4 only, patches welcome: 12 | 13 | * [Control.Lens](lens.pdf) 14 | * [Base (Prelude, Typeclasses, Lists, Misc)](base.pdf) 15 | 16 | ## Currently planned cheat sheets: 17 | 18 | * Pipes (not started) 19 | * IO, Control.Concurrent, Async, IO, Unixy things. 20 | 21 | ## Contributing 22 | 23 | In this early stage, snippets of documentation that you are always looking up 24 | would be really helpful. 25 | 26 | Please feel free to open a pull request with the documentation 27 | (attributed to its author), assuming it's released under a 28 | BSD-3-compatible license. 29 | 30 | ## License 31 | 32 | BSD-3, with attribution to the respective authors from whom we have 33 | stolen bits of documentation: 34 | 35 | - Edward Kmett (Control.Lens) 36 | -------------------------------------------------------------------------------- /all.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/all.pdf -------------------------------------------------------------------------------- /base.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/base.pdf -------------------------------------------------------------------------------- /base.tex: -------------------------------------------------------------------------------- 1 | \input{common/prelude.tex} 2 | 3 | % Spacing for logo 4 | \addtolength{\wpXoffset}{5.5cm} 5 | \addtolength{\wpYoffset}{13.1cm} 6 | 7 | 8 | \usepackage{float} 9 | 10 | \begin{document} 11 | 12 | \CenterWallPaper{0.3}{common/anchor-logo.png} 13 | 14 | 15 | {\huge \bfseries Base -- Folds and Typeclasses \\[0.2cm]} 16 | 17 | \HRule% 18 | 19 | \begin{box1} 20 | \begin{multicols}{2} 21 | 22 | {\Large \bfseries Left associative (foldl)} 23 | 24 | \columnbreak 25 | 26 | {\Large \bfseries Right associative (foldr)} 27 | 28 | \end{multicols} 29 | \begin{multicols}{4} 30 | \columnbreak 31 | 32 | If you are \textbf{reducing to a single value,} then you may get more 33 | performance from a strict left \textbf{foldl'}. 34 | 35 | \includegraphics[width=\linewidth,keepaspectratio=true]{images/foldl.png} 36 | 37 | \columnbreak 38 | 39 | If what you are reducing is \textbf{potentially infinite}, or you are 40 | \textbf{building a structure}, use \textbf{foldr}. 41 | 42 | \columnbreak 43 | 44 | \includegraphics[width=\linewidth,keepaspectratio=true]{images/foldr.png} 45 | 46 | \end{multicols} 47 | 48 | \begin{minted}{haskell} 49 | foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b 50 | foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b 51 | 52 | toList :: Foldable t => t a -> [a] 53 | 54 | and, or :: Foldable t => t Bool -> Bool 55 | any, all :: Foldable t => (a -> Bool) -> t a -> Bool 56 | sum, product :: (Foldable t, Num a) => t a -> a 57 | minimum, maximum :: (Foldable t, Ord a) => t a -> a 58 | minimumBy, maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a 59 | 60 | elem, notElem :: (Foldable t, Eq a) => a -> t a -> Bool 61 | find :: Foldable t => (a -> Bool) -> t a -> Maybe a 62 | \end{minted} 63 | 64 | \begin{multicols}{2} 65 | \begin{minted}{haskell} 66 | > foldl' (flip (:)) [0] [1,2,3] 67 | [3,2,1,0] 68 | 69 | > foldr (:) [5] [1,2,3,4] 70 | [1,2,3,4,5] 71 | 72 | > take 5 $ foldr (:) [] [1..] 73 | [1,2,3,4,5] 74 | \end{minted} 75 | 76 | \columnbreak 77 | 78 | \begin{minted}{haskell} 79 | > all even [1,2,3] 80 | False 81 | 82 | > any even [1,2,3,undefined] 83 | True 84 | 85 | > find (> 42) [1..] 86 | Just 43 87 | \end{minted} 88 | \end{multicols} 89 | \end{box1} 90 | 91 | \begin{box2} 92 | \subsection *{Applicative Traversals/Folds} 93 | 94 | \begin{minted}{haskell} 95 | traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) 96 | for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b) 97 | sequenceA :: Applicative f => t (f a) -> f (t a) 98 | 99 | > for [1000000, 2000000] $ \t -> threadDelay t >> getCurrentTime 100 | [2015-04-29 05:24:30.040399 UTC,2015-04-29 05:24:32.042665 UTC] 101 | \end{minted} 102 | \end{box2} 103 | 104 | \begin{multicols}{2} 105 | 106 | \begin{box1} 107 | \subsection *{Functor} 108 | 109 | \begin{minted}{haskell} 110 | class Functor (f :: * -> *) where 111 | fmap :: (a -> b) -> f a -> f b 112 | (<$) :: a -> f b -> f a 113 | \end{minted} 114 | \end{box1} 115 | 116 | \begin{box2} 117 | \subsection *{Control.Applicative} 118 | \begin{minted}{haskell} 119 | class Functor f => Applicative f where 120 | pure :: a -> f a 121 | (<*>) :: f (a -> b) -> f a -> f b 122 | (*>) :: f a -> f b -> f b 123 | (<*) :: f a -> f b -> f a 124 | \end{minted} 125 | \end{box2} 126 | 127 | \begin{box1} 128 | \subsection *{Control.Monad} 129 | \begin{minted}{haskell} 130 | class Applicative m => Monad m where 131 | (>>=) :: m a -> (a -> m b) -> m b 132 | (>>) :: m a -> m b -> m b 133 | return :: a -> m a 134 | fail :: String -> m a 135 | 136 | (>=>) :: Monad m 137 | => (a -> m b) -> (b -> m c) -> a -> m c 138 | 139 | join :: Monad m => m (m a) -> m a 140 | ap :: Monad m => m (a -> b) -> m a -> m b 141 | \end{minted} 142 | 143 | \end{box1} 144 | 145 | \end{multicols} 146 | \newpage 147 | 148 | {\huge \bfseries Base -- Lists and misc \\[0.2cm]} 149 | 150 | \HRule% 151 | 152 | \begin{multicols}{2} 153 | \begin{box1} 154 | \subsection *{Data.List} 155 | \begin{minted}{haskell} 156 | intersperse :: a -> [a] -> [a] 157 | > intersperse ',' "abcde" == "a,b,c,d,e" 158 | 159 | intercalate :: a -> [a] -> [a] 160 | > intercalate " love " ["ponies", "ducks"] 161 | "ponies love ducks" 162 | 163 | subsequences, permutations :: [a] -> [[a]] 164 | > subsequences "abc" 165 | ["","a","b","ab","c","ac","bc","abc"] 166 | > permutations "abc" 167 | ["abc","bac","cba","bca","cab","acb"] 168 | 169 | scanl :: (b -> a -> b) -> b -> [a] -> [b] 170 | > scanl f z [x1, x2, ...] 171 | [z, z `f` x1, (z `f` x1) `f` x2, ...] 172 | > take 8 $ fix (\fib -> scanl (+) 1 (0:fib)) 173 | [1,1,2,3,5,8,13,21] 174 | 175 | iterate :: (a -> a) -> a -> [a] 176 | > iterate f x 177 | [x, f x, f (f x), ...] 178 | > take 10 $ iterate (*2) 1 179 | [1,2,4,8,16,32,64,128,256,512] 180 | 181 | replicate :: Int -> a -> [a] 182 | repeat :: a -> [a] 183 | cycle :: [a] -> [a] 184 | 185 | :: Int -> [a] -> ([a], [a]) 186 | > splitAt n xs 187 | (take n xs, drop n xs) 188 | 189 | takeWhile, dropWhile 190 | :: (a -> Bool) -> [a] -> [a] 191 | > takeWhile (< 3) [1,2,3,4,1,2,3,4] 192 | [1,2] 193 | 194 | isPrefixof, isSuffixOf, isInfixOf 195 | :: Eq a => [a] -> [a] -> Bool 196 | 197 | lines, words :: String -> [String] 198 | unwords, unlines :: [String] -> String 199 | 200 | nub :: Eq a => [a] -> [a] 201 | > nub [1,2,2,3,2] 202 | [1,2,3] 203 | 204 | delete :: Eq a => a -> [a] -> [a] 205 | > delete 'a' "banana" 206 | "bnana" 207 | 208 | (\\), union, intersect 209 | :: Eq a => [a] -> [a] -> [a] 210 | > (xs ++ ys) \\ xs -- difference 211 | ys 212 | \end{minted} 213 | \end{box1} 214 | 215 | \begin{box2} 216 | \subsection *{Commonly re-defined} 217 | \begin{minted}{haskell} 218 | strip :: String -> String 219 | strip = 220 | join fmap (reverse . dropWhile isSpace) 221 | 222 | > strip " a " 223 | "a" 224 | 225 | pairs :: [a] -> [(a, a)] 226 | pairs = zip <*> tail 227 | 228 | > pairs [1] 229 | [] 230 | > pairs [1,2,3] 231 | [(1,2),(2,3)] 232 | \end{minted} 233 | \end{box2} 234 | 235 | \begin{box1} 236 | \subsection *{Data.Function} 237 | \begin{minted}{haskell} 238 | fix :: (a -> a) -> a 239 | > fix $ \f n -> 240 | > if n < 0 then [] else n : f (n - 1)) 5 241 | [5,4,3,2,1,0] 242 | 243 | on :: (b -> b -> c) 244 | -> (a -> b) -> a -> a -> c 245 | > (*) `on` f 246 | \x y -> f x * f y. 247 | > sortBy (compare `on` length) ["bb", "a"] 248 | ["a","bb"] 249 | 250 | \end{minted} 251 | \end{box1} 252 | 253 | 254 | \begin{box2} 255 | \subsection *{Debug.Trace} 256 | 257 | The usual output stream is \textbf{stderr}. 258 | 259 | \begin{minted}{haskell} 260 | trace :: String -> a -> a 261 | traceShow :: Show a => a -> b -> b 262 | traceShowId :: Show a => a -> a 263 | traceStack :: String -> a -> a 264 | traceIO :: String -> IO () 265 | traceM :: Monad m => String -> m () 266 | traceShowM :: (Show a, Monad m) => a -> m () 267 | 268 | > trace ("call f with x = " ++ show x) (f x) 269 | > g x y = traceShow (x, y) (x + y) 270 | \end{minted} 271 | \end{box2} 272 | 273 | \begin{box1} 274 | \subsection *{Control.Arrow} 275 | \begin{minted}{haskell} 276 | class Category a => Arrow a where 277 | arr :: (b -> c) -> a b c 278 | first :: a b c -> a (b,d) (c,d) 279 | second :: a b c -> a (d,b) (d,c) 280 | (***) :: a b c -> a b' c' -> a (b,b') (c,c') 281 | (&&&) :: a b c -> a b c' -> a b (c,c') 282 | \end{minted} 283 | \end{box1} 284 | 285 | \end{multicols} 286 | \end{document} 287 | -------------------------------------------------------------------------------- /common/anchor-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/common/anchor-logo.png -------------------------------------------------------------------------------- /common/prelude.tex: -------------------------------------------------------------------------------- 1 | \documentclass[10pt]{article} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage[english]{babel} 4 | 5 | \usepackage{multicol} 6 | \usepackage[none]{hyphenat} 7 | \usepackage{color} 8 | \usepackage{xcolor} 9 | \usepackage{comment} 10 | \usepackage{tikz} 11 | \usepackage{alltt} 12 | \usetikzlibrary{backgrounds,calc} 13 | \usepackage{minted} 14 | \usepackage[framemethod=TikZ]{mdframed} 15 | \usepackage{wallpaper} 16 | \usepackage{parskip} 17 | \setlength{\parindent}{0pt} 18 | \usepackage[a4paper, top=1.5cm, bottom=0.75cm, left=1.3cm, right=1.3cm, includefoot]{geometry} 19 | \usepackage{titlesec} 20 | \usepackage{fancyhdr} 21 | \pagestyle{fancy} 22 | \pagenumbering{gobble} 23 | 24 | 25 | % Github image 26 | \newcommand{\github}{% 27 | \begin{tikzpicture}[y=0.3pt, x=0.3pt,yscale=-1, inner sep=0pt, outer sep=0pt,opacity=0.4] 28 | \begin{scope}[shift={(506.69823,386.92617)}] 29 | \path[fill=black] (116.9933,59.7217) .. controls (116.9933,71.2283) and 30 | (107.6655,80.5562) .. (96.1589,80.5562) .. controls (84.6524,80.5562) and 31 | (75.3245,71.2283) .. (75.3245,59.7217) .. controls (75.3245,48.2152) and 32 | (84.6524,38.8873) .. (96.1589,38.8873) .. controls (107.6654,38.8873) and 33 | (116.9933,48.2152) .. (116.9933,59.7217) -- cycle; 34 | \path[cm={{0.88462,0.0,0.0,0.88462,(11.09526,6.89097)}},fill=white] 35 | (116.9933,59.7217) .. controls (116.9933,71.2283) and (107.6655,80.5562) .. 36 | (96.1589,80.5562) .. controls (84.6524,80.5562) and (75.3245,71.2283) .. 37 | (75.3245,59.7217) .. controls (75.3245,48.2152) and (84.6524,38.8873) .. 38 | (96.1589,38.8873) .. controls (107.6654,38.8873) and (116.9933,48.2152) .. 39 | (116.9933,59.7217) -- cycle; 40 | \path[fill=black,nonzero rule] (103.4671,45.2878) .. controls (102.9322,45.4374) 41 | and (101.2003,46.2576) .. (100.5403,46.6739) -- (100.1099,46.9454) -- 42 | (99.4882,46.8019) .. controls (99.0810,46.7080) and (98.1204,46.6415) .. 43 | (96.7048,46.6094) .. controls (94.4953,46.5593) and (93.4339,46.6361) .. 44 | (92.2380,46.9324) -- (91.6450,47.0793) -- (90.9468,46.6426) .. controls 45 | (90.0955,46.1101) and (88.7784,45.4948) .. (88.1825,45.3512) .. controls 46 | (87.9348,45.2916) and (87.5225,45.2429) .. (87.2643,45.2429) .. controls 47 | (86.8530,45.2429) and (86.7816,45.2733) .. (86.6817,45.4916) .. controls 48 | (86.3049,46.3144) and (86.1702,48.1697) .. (86.3982,49.3940) -- 49 | (86.5087,49.9870) -- (86.0485,50.6088) .. controls (85.4184,51.4600) and 50 | (84.9876,52.3958) .. (84.8509,53.2104) .. controls (84.6439,54.4443) and 51 | (84.8398,57.3849) .. (85.1880,58.2702) .. controls (85.2564,58.4443) and 52 | (85.2939,58.4403) .. (81.6976,58.6338) .. controls (79.2203,58.7672) and 53 | (77.4880,58.9815) .. (77.2948,59.1788) .. controls (77.1683,59.3080) and 54 | (77.2021,59.3161) .. (77.6325,59.2604) .. controls (79.8802,58.9695) and 55 | (83.0680,58.7293) .. (84.6818,58.7293) .. controls (85.3322,58.7293) and 56 | (85.3437,58.7337) .. (85.4709,59.0402) .. controls (85.5424,59.2123) and 57 | (85.5936,59.3574) .. (85.5857,59.3654) .. controls (85.5778,59.3733) and 58 | (84.8826,59.4288) .. (84.0409,59.4888) .. controls (82.1375,59.6245) and 59 | (80.3024,59.8884) .. (78.6942,60.2577) .. controls (77.5177,60.5279) and 60 | (77.1884,60.6573) .. (77.3264,60.7953) .. controls (77.3578,60.8267) and 61 | (77.9386,60.7190) .. (78.6081,60.5575) .. controls (80.6932,60.0548) and 62 | (83.4463,59.6858) .. (85.1122,59.6858) .. controls (85.7817,59.6858) and 63 | (85.8050,59.6938) .. (85.9497,59.9727) .. controls (86.1509,60.3606) and 64 | (87.1973,61.4638) .. (87.6756,61.7923) .. controls (88.7575,62.5354) and 65 | (90.1146,63.0487) .. (91.7311,63.3262) .. controls (92.3241,63.4280) and 66 | (92.8529,63.5117) .. (92.9028,63.5117) .. controls (92.9519,63.5117) and 67 | (92.8171,63.7221) .. (92.6084,63.9708) .. controls (92.2151,64.4395) and 68 | (91.8427,65.1574) .. (91.8393,65.4534) .. controls (91.8343,65.8877) and 69 | (90.1911,66.2247) .. (89.1390,66.0071) .. controls (88.4365,65.8618) and 70 | (87.9449,65.5203) .. (87.3370,64.7552) .. controls (86.5997,63.8274) and 71 | (86.0013,63.2318) .. (85.6000,63.0268) .. controls (85.1313,62.7874) and 72 | (84.1718,62.7744) .. (83.9782,63.0048) .. controls (83.8657,63.1387) and 73 | (83.8975,63.1954) .. (84.2322,63.4586) .. controls (85.1908,64.2122) and 74 | (85.6680,64.7934) .. (86.1681,65.8169) .. controls (86.7336,66.9742) and 75 | (87.2885,67.5731) .. (88.1825,67.9913) .. controls (88.6992,68.2330) and 76 | (88.8042,68.2463) .. (90.1911,68.2463) -- (91.6546,68.2463) -- 77 | (91.6259,70.0923) -- (91.5972,71.9383) -- (91.2050,72.2922) .. controls 78 | (90.9850,72.4908) and (90.6785,72.7603) .. (90.5068,72.9061) .. controls 79 | (90.0483,73.2955) and (90.1529,73.4104) .. (90.9946,73.4418) .. controls 80 | (91.6450,73.4662) and (91.7691,73.4390) .. (92.3241,73.1503) .. controls 81 | (93.3630,72.6098) and (93.3667,72.5983) .. (93.3667,69.8628) .. controls 82 | (93.3667,67.3377) and (93.4455,66.7059) .. (93.8107,66.3047) -- 83 | (94.0458,66.0464) -- (93.9980,69.2506) .. controls (93.9695,71.1540) and 84 | (93.9075,72.6024) .. (93.8449,72.8183) .. controls (93.7868,73.0192) and 85 | (93.6134,73.3252) .. (93.4575,73.5022) .. controls (93.3059,73.6744) and 86 | (93.1754,73.9155) .. (93.1754,74.0235) .. controls (93.1754,74.1976) and 87 | (93.2328,74.2243) .. (93.6058,74.2243) .. controls (94.3519,74.2243) and 88 | (95.3191,73.5586) .. (95.6209,72.8374) .. controls (95.8285,72.3417) and 89 | (95.9492,70.6280) .. (95.9492,68.1794) -- (95.9492,65.9029) -- 90 | (96.4179,65.9029) -- (96.4465,69.1311) .. controls (96.4752,72.3544) and 91 | (96.4756,72.3599) .. (96.7144,72.8374) .. controls (97.1209,73.6505) and 92 | (98.5189,74.4873) .. (99.0195,74.2173) .. controls (99.2785,74.0776) and 93 | (99.2470,73.9374) .. (98.8154,73.3061) .. controls (98.5996,72.9905) and 94 | (98.3935,72.5452) .. (98.3372,72.2731) .. controls (98.2088,71.6514) and 95 | (98.2544,66.1949) .. (98.3882,66.1752) .. controls (98.4417,66.1673) and 96 | (98.5682,66.3047) .. (98.6752,66.4864) .. controls (98.8508,66.7849) and 97 | (98.8704,67.0316) .. (98.9143,69.4898) .. controls (98.9477,71.3645) and 98 | (98.9985,72.2310) .. (99.0833,72.3783) .. controls (99.2883,72.7344) and 99 | (99.9568,73.2398) .. (100.3777,73.3570) .. controls (100.6002,73.4189) and 100 | (101.0568,73.4562) .. (101.4011,73.4406) .. controls (102.2046,73.4043) and 101 | (102.2524,73.2299) .. (101.5924,72.7428) .. controls (100.6531,72.0496) and 102 | (100.6840,72.1775) .. (100.6746,68.9637) .. controls (100.6656,65.9699) and 103 | (100.6109,65.4703) .. (100.2007,64.6499) .. controls (100.0812,64.4108) and 104 | (99.8134,64.0644) .. (99.5982,63.8704) -- (99.2108,63.5213) -- 105 | (99.6603,63.4617) .. controls (100.5690,63.3414) and (102.0372,63.0328) .. 106 | (102.6446,62.8345) .. controls (104.1654,62.3382) and (105.5084,61.3208) .. 107 | (106.1445,60.1832) -- (106.4227,59.6858) -- (106.9679,59.6858) .. controls 108 | (108.9956,59.6858) and (112.7503,60.2177) .. (114.7632,60.7901) .. controls 109 | (114.9162,60.8337) and (114.9832,60.8090) .. (114.9832,60.7092) .. controls 110 | (114.9832,60.3420) and (111.4059,59.7105) .. (108.1061,59.4950) .. controls 111 | (107.2931,59.4419) and (106.6181,59.3838) .. (106.5996,59.3654) .. controls 112 | (106.5815,59.3473) and (106.6145,59.1932) .. (106.6713,59.0306) -- 113 | (106.7765,58.7293) -- (107.9817,58.7323) .. controls (109.6496,58.7363) and 114 | (111.7789,58.8872) .. (113.5293,59.1252) .. controls (114.8684,59.3073) and 115 | (115.2129,59.3130) .. (115.0501,59.1502) .. controls (114.8456,58.9456) and 116 | (112.1137,58.6482) .. (109.3399,58.5285) .. controls (108.0008,58.4707) and 117 | (106.8944,58.4168) .. (106.8865,58.4089) .. controls (106.8785,58.4010) and 118 | (106.9394,58.0694) .. (107.0204,57.6772) .. controls (107.1184,57.2030) and 119 | (107.1719,56.3764) .. (107.1782,55.2382) .. controls (107.1862,53.7174) and 120 | (107.1624,53.4295) .. (106.9708,52.7704) .. controls (106.6953,51.8235) and 121 | (106.3173,51.0734) .. (105.7225,50.2931) -- (105.2557,49.6810) -- 122 | (105.2940,48.0598) .. controls (105.3295,46.5581) and (105.3160,46.3927) .. 123 | (105.1123,45.8168) -- (104.8923,45.1951) -- (104.4140,45.1760) .. controls 124 | (104.1462,45.1653) and (103.7296,45.2145) .. (103.4671,45.2879) -- cycle; 125 | \end{scope} 126 | \end{tikzpicture} 127 | } 128 | 129 | \lfoot{ 130 | \github https://github.com/anchor/haskell-cheat-sheets 131 | } 132 | 133 | % spacing 134 | \titlespacing*{\subsection}{0pt}{3pt}{5pt} 135 | 136 | % Anchor colors 137 | \definecolor{anchorstripe}{HTML}{50a0e0} 138 | \definecolor{anchorbase}{HTML}{356895} 139 | \definecolor{anchorextra}{HTML}{27ccc0} 140 | \definecolor{anchoraccent}{HTML}{F78224} 141 | \definecolor{shadecolor}{HTML}{27ccc0} 142 | 143 | % Custom commands 144 | \newcommand{\HRule}[1][\medskipamount]{\par 145 | \vspace*{\dimexpr-\parskip-\baselineskip+#1} 146 | \noindent\rule{\linewidth}{0.1mm}\par 147 | \vspace*{\dimexpr-\parskip-.5\baselineskip+#1}} 148 | 149 | \newmdenv[% 150 | linecolor=anchorextra,% 151 | backgroundcolor=anchorextra!1,% 152 | outerlinewidth = 1,% 153 | roundcorner=2pt,% 154 | ]{box2} 155 | 156 | \newmdenv[% 157 | linecolor=anchoraccent,% 158 | backgroundcolor=anchoraccent!1,% 159 | outerlinewidth = 1,% 160 | roundcorner=2pt,% 161 | ]{box1} 162 | 163 | 164 | -------------------------------------------------------------------------------- /images/foldl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/images/foldl.png -------------------------------------------------------------------------------- /images/foldr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/images/foldr.png -------------------------------------------------------------------------------- /lens.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchor/haskell-cheat-sheets/48b1980ef99bf723ac6e001b33f0dccc90386ba7/lens.pdf -------------------------------------------------------------------------------- /lens.tex: -------------------------------------------------------------------------------- 1 | \input{common/prelude.tex} 2 | 3 | % Spacing for logo 4 | \addtolength{\wpXoffset}{5.5cm} 5 | \addtolength{\wpYoffset}{13.1cm} 6 | 7 | \begin{document} 8 | 9 | \CenterWallPaper{0.3}{common/anchor-logo.png} 10 | 11 | 12 | {\huge \bfseries Control.Lens (viewing) \\[0.2cm]} 13 | 14 | \HRule% 15 | 16 | \begin{multicols}{2} 17 | 18 | \begin{box1} 19 | \subsection *{Getting with Getters} 20 | 21 | Any function $(s \to a)$ can be flipped into continuation passing style, $(a \to r) 22 | \to s \to r$ and decorated with \textbf{Const} to obtain: 23 | 24 | \begin{minted}{haskell} 25 | type Getting r s a = 26 | (a -> Const r a) -> s -> Const r s 27 | \end{minted} 28 | A \textbf{Getter} describes how to retrieve a single value in a way that can be composed 29 | with other \textbf{LensLike} constructions. 30 | 31 | When you see this in a type signature it indicates that you can pass the 32 | function a \textbf{Lens}, \textbf{Getter}, \textbf{Traversal}, \textbf{Fold}, 33 | \textbf{Prism}, \textbf{Iso}, or one of the indexed 34 | variants, and it will just ``do the right thing''. 35 | \end{box1} 36 | 37 | \begin{box2} 38 | \subsection *{Safe head} 39 | Perform a safe head of a \textbf{Fold} or \textbf{Traversal} or retrieve 40 | \textbf{Just} the result from a \textbf{Getter} or \textbf{Lens}. 41 | 42 | $ (\ \hat{}\,?) \equiv flip\;preview $ 43 | 44 | \begin{minted}{haskell} 45 | (^?) :: s -> Getting (First a) s a -> Maybe a 46 | 47 | > Right 4 ^?_Left 48 | Nothing 49 | > "world" ^? ix 3 50 | Just `l' 51 | \end{minted} 52 | \end{box2} 53 | 54 | \begin{box1} 55 | 56 | \subsection *{Viewing lenses} 57 | 58 | View the value pointed to by a \textbf{Getter} or \textbf{Lens} or the result 59 | of folding over all the results of a \textbf{Fold} or \textbf{Traversal} that 60 | points at a monoidal values. 61 | 62 | This is the same operation as \textbf{view} with the arguments flipped. 63 | 64 | \begin{minted}{haskell} 65 | (^.) :: s -> Getting a s a -> a 66 | 67 | > (0, -5)^._2.to abs 68 | 5 69 | > ["a", "b", "c"] ^. traversed 70 | "abc" 71 | \end{minted} 72 | \end{box1} 73 | 74 | \begin{box2} 75 | \subsection*{Using MonadState} 76 | 77 | Use the target of a \textbf{Lens}, \textbf{Iso}, or \textbf{Getter} in the 78 | current state, or use a summary of a \textbf{Fold} or \textbf{Traversal} that 79 | points to a monoidal value. 80 | 81 | \begin{minted}{haskell} 82 | use :: MonadState s m => Getting a s a -> m a 83 | 84 | > evalState (use _1) (1,2) 85 | 1 86 | > evalState (uses _1 length) ("hello","") 87 | 5 88 | \end{minted} 89 | \end{box2} 90 | 91 | \columnbreak 92 | 93 | \begin{box1} 94 | \subsection *{Folding Foldables} 95 | \begin{minted}{haskell} 96 | type Fold s a = 97 | forall m. Monoid m => Getting m s a 98 | \end{minted} 99 | A \textbf{Fold s a} is a generalization of something \textbf{Foldable}. It 100 | allows you to extract multiple results from a container. Every \textbf{Getter} 101 | is a valid \textbf{Fold} that simply doesn't use the Monoid it is passed. 102 | 103 | If there exists a \textbf{foo} method that expects a 104 | \textbf{Foldable (f a)}, then there should be a \textbf{fooOf} method that 105 | takes a \textbf{Fold s a} and a value of type \textbf{s}. 106 | 107 | \end{box1} 108 | 109 | \begin{box2} 110 | \subsection *{Extracting lists from Folds} 111 | 112 | Extract a list of the targets of a \textbf{Fold}, an infix version of 113 | \textbf{toListOf}. 114 | 115 | $ toList\;xs \equiv xs\;\hat{}.. folded $ 116 | 117 | \begin{minted}{haskell} 118 | (^..) :: s -> Getting (Endo [a]) s a -> [a] 119 | 120 | > [[1,2],[3]] ^.. traverse . traverse 121 | [1,2,3] 122 | > (1,2) ^.. both 123 | [1,2] 124 | \end{minted} 125 | \end{box2} 126 | 127 | \begin{box1} 128 | \subsection *{Checking for matches} 129 | 130 | Check to see if this \textbf{Fold} or \textbf{Traversal} matches 1 or more entries. For the 131 | opposite, use \textbf{hasn't}. 132 | 133 | \begin{minted}{haskell} 134 | has :: Getting Any s a -> s -> Bool 135 | 136 | > has (element 0) [] 137 | False 138 | > has _Right (Left 12) 139 | False 140 | > hasn't _Right (Left 12) 141 | True 142 | \end{minted} 143 | \end{box1} 144 | 145 | 146 | \begin{box2} 147 | \subsection*{Indexed Getters} 148 | For most operations, there is an indexed variant which will work as expected if 149 | the underlying target supports a notion of \textbf{Indexing}. 150 | 151 | \begin{minted}{haskell} 152 | > ["ab", "c"] ^@.. itraversed <.> itraversed 153 | [((0,0),'a'),((0,1),'b'),((1,0),'c')] 154 | > "hello" ^@.. itraversed . indices even 155 | [(0,'h'),(2,'l'),(4,'o')] 156 | 157 | > ifind (\i k -> i > k) [1,2,2,2] 158 | Just (3,2) 159 | \end{minted} 160 | \end{box2} 161 | \end{multicols} 162 | \newpage 163 | 164 | {\huge \bfseries Control.Lens (setting) \\[0.2cm]} 165 | 166 | \HRule% 167 | 168 | \begin{multicols}{2} 169 | 170 | \begin{box1} 171 | \subsection *{Modifying records with Setters} 172 | A \textbf{Setter s t a b} is a generalization of fmap from \textbf{Functor}. It 173 | allows you to map into a structure and change out the contents, but it isn't 174 | strong enough to allow you to enumerate those contents. Starting with 175 | $fmap :: Functor f \Rightarrow (a \to b) \to f a \to f b$ we monomorphize the type 176 | to obtain $(a \to b) \to s \to t$ and then decorate it with Identity to obtain: 177 | 178 | \begin{minted}{haskell} 179 | type Setter s t a b = 180 | (a -> Identity b) -> s -> Identity t 181 | \end{minted} 182 | 183 | Every \textbf{Traversal} is a valid \textbf{Setter}, since \textbf{Identity} is 184 | \textbf{Applicative}. 185 | 186 | \end{box1} 187 | 188 | \begin{box2} 189 | \subsection *{Modifying with a function} 190 | 191 | Modifies the target of a \textbf{Lens} or all of the targets of a 192 | \textbf{Setter} or \textbf{Traversal} with a user supplied function. 193 | 194 | This is an infix version of \textbf{over}. 195 | 196 | \begin{minted}{haskell} 197 | (%~) :: Profunctor p 198 | => Setting p s t a b -> p a b -> s -> t 199 | 200 | > traverse %~ even $ [1,2,3] 201 | [False,True,False] 202 | \end{minted} 203 | \end{box2} 204 | 205 | \begin{box1} 206 | \subsection *{Modifying with a constant value} 207 | 208 | Replace the target of a \textbf{Lens} or all of the targets of a 209 | \textbf{Setter} or \textbf{Traversal} with a constant value. 210 | 211 | \begin{minted}{haskell} 212 | (.~) :: ASetter s t a b -> b -> s -> t 213 | 214 | > [1,2,3] & element 0 .~ 3 215 | [3,2,3] 216 | > [1,2,3] & traversed . filtered odd .~ 0 217 | [0,2,0] 218 | \end{minted} 219 | \end{box1} 220 | 221 | \begin{box2} 222 | \subsection *{Prisms and Isos} 223 | 224 | An \textbf{Iso} is a pair of inverse functions. You can invert an \textbf{Iso} with \textbf{from}. 225 | 226 | \textbf{Prism}s can be thought of as \textbf{Iso}s that can fail in one 227 | direction. You can invert a \textbf{Prism} with \textbf{re}. 228 | 229 | \begin{minted}{haskell} 230 | type Prism s t a b 231 | forall p f. (Choice p, Applicative f) => 232 | p a (f b) -> p s (f t) 233 | type Prism' s a = Prism s s a a 234 | 235 | prism :: (b -> t) 236 | -> (s -> Either t a) 237 | -> Prism s t a b 238 | prism' :: (a -> s) 239 | -> (s -> Maybe a) 240 | -> Prism' s a 241 | 242 | > 5^.re _Left ^?! _Left 243 | 5 244 | > _Left # 1 245 | Left 1 246 | 247 | type Iso s t a b = 248 | forall p f. (Profunctor p, Functor f) => 249 | p a (f b) -> p s (f t) 250 | type Iso' s a = Iso s s a a 251 | 252 | iso :: (s -> a) -> (b -> t) -> Iso s t a b 253 | from :: AnIso s t a b -> Iso b a t s 254 | 255 | > 'a' ^. from enum 256 | 97 257 | > 97 ^. enum :: Char 258 | 'a' 259 | 260 | > Map.empty & at "hi" 261 | > . non Map.empty 262 | > . at "world" ?~ "!" 263 | fromList [("hi",fromList [("world","!")])] 264 | \end{minted} 265 | 266 | \end{box2} 267 | 268 | \end{multicols} 269 | 270 | \begin{box2} 271 | \subsection *{Some setting operators} 272 | \begin{tabular}{ l l l l l } 273 | \textbf{Operator} & \textbf{W/result} & \textbf{W/state} & \textbf{W/both} & \textbf{Action}\\ 274 | \hline 275 | \verb!+~ ! & \verb!<+~ ! & \verb!+= ! & \verb!<+= ! & Add to target(s)\\ 276 | \verb!-~ ! & \verb!<-~ ! & \verb!-= ! & \verb!<-= ! & Subtract from target(s)\\ 277 | \verb!*~ ! & \verb!<*~ ! & \verb!*= ! & \verb!<*= ! & Multiply target(s)\\ 278 | \verb!//~! & \verb!~! & \verb!<<>~! & \verb!<>=! & \verb!<<>=! & mappend to the target monoidal value(s)\\ 285 | \end{tabular} 286 | \end{box2} 287 | 288 | 289 | \end{document} 290 | --------------------------------------------------------------------------------