Functional programming uses a set of reusable patterns called the 'functional toolbox' that transform functions and values between different computational contexts (normal world vs. effect worlds like options, lists, or async operations). The core tools include: (1) Map (functor) - lifts normal functions into effect worlds so they can operate on effect-typed values without manual unwrapping; (2) Return/Pure/Unit - lifts individual values from normal world into effect worlds; (3) Bind (monad) - converts diagonal 'world-crossing' functions (which start in normal world and end in effect world) into horizontal functions that can be composed linearly, solving the 'pyramid of doom' problem of nested conditionals; (4) Apply/Applicative - combines multiple effect-typed values in parallel rather than sequentially, enabling features like parallel validation where all errors are collected at once. These tools are based on mathematical structures like monoids (closure, associativity, identity element) that enable powerful patterns including parallel computation, incremental accumulation, and clean error handling through railway-oriented programming.
Functional Programming Toolkit: Monads, Functors, and More
Added:okay welcome welcome to the functional programming toolkit this is a talk for kind of beginner to intermediate people interested in functional programming and you've done a little bit but there's a lot of things you don't understand like monads for example or functors and all this jargon so the point of this talk is really to go through that jargon and hopefully explain it to you in a way that sort of demystifies it so it's useful if you've done a little bit of functional programming before but even if you haven't I think you'll probably be able to understand what I'm talking about because I use lots of little pictures so my name is Scott volution and I have a website F sharp for fun and profit the code examples in this talk will be in F sharp but it's not not a lot of code in this token so don't worry about if you don't understand the code so the main questions start with is why do functional programmers use so many strange words and it comes across as very scary to most people there's words like functor cat morphism applicative carrying monoid and monad the most scary word of all and I think the problem is these words kind of sound scary but they're not actually scary concepts if you understood what they were I mean you might be like Homer here and think I can't possibly understand any of this stuff it's way too complicated but it's not I don't think it's scary I think it's unfamiliar so if you knew what the words meant or at least would demystified a bit then you might be like Homer here and you might say okay you mapable if I call it a map up I could understand that or a collapsible or an aggregator for whatever the word is it doesn't really matter what the words are but these words don't sound as scary as the sort of mathematical words so that's really the goal of this talk is to demystify you may not know what they mean they still be unfamiliar but it's they're not scary you know what's really scary is object-oriented programming and just because you're used to it you don't think is scary but if I'm a brand-new object-oriented program there's all these words like polymorphism in the hair and generics and co-variants and solid and solid is five other things and there's IOC and di and ABC interview you know you just don't realize how scary it is if you are inexperienced there were person so don't ever say that functional programming is a scale words because oh it's just as bad its jargon like we just used to used to it okay so there's four particular words that I want to talk about in this talk and like I say these are mathematical words and you might think well this is kind of an academic abstract theoretical kind of thing but it actually turns out these are very useful tools and again if you demystified it hopefully you'll see by the end of this talk they are actually useful tools so there's something called what I call the functional toolbox and it's the analogous with a a real toolbox and a second in a real toolbox you have all these different tools that you know and each tool does one particular thing well and you know if you're an experienced person you know which tool to use for which thing and a functional programmer has a bunch of tools to you know map return bind whatever all these tools have names and if you're an experienced person you know you know which tool to use in which situation and basically it's about eleven kind of important tools you need to know about as maybe you know ten other ones which are not quite as important but if you know these how to use these eleven tools you can pretty much do everything in front of the programming so this is a problem-solving tool box it's not an academic tool boxes for really getting a hands dirty so what are the kinds of problems that functional programs need to solve well the first problem they need to solve is composition because everything in functional programming is composition is the fundamental principle and I'll talk about in a second how do you combine things how do you aggregate things that's a common problem in both oh and functional how do you iterate through things how do you work with effects now this is a kind of more functional programming thing they like a plugin let's talk about effects all the time and what do we mean by effects and I'll explain what I mean by effects but these effects are kind of tricky to work with sometimes and so you have to mix things which you're effects non effects where you might need to chain them or you need to work in parallel there's all different things you need to work with when you have effects and there's a bunch of tools just without superposition so these are the kind of words that you'll see a lot composition uses to compose key words iteration isn't generally called fold in functional people combine and reduce Mack and return sign which is also called flat map apply and zip sequence reverse these are the kinds of names of functions or names of the tools that you use a lot if you're doing functional programming and of course if you enter the jargon these things have actually names so combination is generally called amyloid when you work with different kinds of effects that's you use a functor if you want to chain effects as a monad if you want to work in parallel as an applicative so don't worry about this I'm going to explain hopefully by the end of talk all these things hopefully they make sense and even if they don't make sense I lived a little bit less mysterious that's the whole point so this talk is good it's going to be one of those things like those tourist buses where you go around the city and you'd like stop for one minute in each famous place you don't really get a chance to look around but at least you actually see the sights so that's what this is as a whirlwind tour of the sites you can't possibly understand everything you know in one talk but hopefully if you demystify and you go away you know you can say oh I can and I can at least not be scared I can go in and learn more about it later on when I get a chance so start with some principles of statically typed functional programming for people who are newbies the first thing is the functions of things and like luckily as little well we attract analogy and the composition is used everywhere so there's no inheritance there's nothing else's everything is composition and if you know how to use Lego you know how to do composition because this is exactly the same so let's look at functions as things so a function is a little thing I like to use the railway track analogy in this little tunnel tunnel transformation something goes in if something comes out in this case an apple go and it turns into banana so this is a we call this an apple - banana faction Maya trot it transform samples into bananas and the thing about functions is they are standalone things they're not attached to any class because they're things they can be used just like you might use an integer or a string or something you can pass them around as parameters you can put them in lists you know you can do all sorts of things because they're just things just like everything else and this standalone thing is really really important because stand alone is another word for reusable if it's on its own it can be reused in any context if it's part of a class it's really hard to sort of extract it from that class and we use it in a different context but all the functions in front of the program they are standalone functions so here's an example of a function has a normal input but it has an output which is a function here's an example of a function that has a function as an input and a normal outlet here's a function with a normal input and a normal output but it's got this extra function which can be either sort of parameterizing it and this would be called the strategy pattern in our so this is that's it that's really everything you need to know about on to the programming right there if you understand that you understand everything you can see it can get really complex it's a very simple foundation but you can have functions that return other functions that generate other functions which uses premises other function it can get very complicated but the fundamental principles are basically just what I said in the last few minutes and most the tools in the functional toolbox that I'm going to be talking about it our function transformers they take functions in and they spit other functions on so having functions come in and functions come out that's a really really common thing in functional programming so the next principle which is really important is composition so I'm gonna talk about Lego for a second because everyone understands how Lego works hopefully and Lego actually has a sort of philosophy right which is that everything is designed to be connected to everything else right you don't have LEGO pieces which don't fit to other LEGO pieces and if you connect your LEGO pieces together you get another piece which can still be connected to other pieces right you never have you never run into a wall where Owen at any more LEGO pieces cuz I've run out of dots or something you know and they're reusable so here's some Lego every single piece in Lego has little dots so they're designed to be connected and when you start assembling them you know you don't you can just keep adding and adding pieces you know they're designed to be that way that you never sort of hit a boundary you can add two pieces and that makes another piece you having more pieces you don't need a special adapter you don't say well this piece won't fit with this piece because then I need a special sort of adapter pattern to make two bits of Lego fit no you don't have an adapter pattern in Lego right they just literally connect straight together and you can keep adding and adding and adding and you can make really really big things out of Lego add all the small pieces and here's the reusability thing right you can you can make something and then you can disassemble it and make something else the pieces themselves do not have any strings attached to literally they don't have any strings attached if they had strings attached they'll get tangled up the springs will get tangled up and this is one of the goals of functional programming is that all the functions that you built don't have any strings attached and because of that reusable they're not attached to a particular context they're not you don't have to kind of extract them in order to reuse and they literally are designed to be reusable from the very beginning so you can make really big things from small things in Lego that's what I'd like to call the power of composition now let's look at the functional programming philosophy which is very similar to the lego philosophy and this is by the rent automatic statically typed functional programming dynamic type generic function program is similar that there's a little bit of difference so in front of program you try to design functions that do one thing well the solid principles applied to functional programming too but the functions can be reused so you design your functions to be reusable and you design them to work together and you expect the output error function might be the input to some other function you know you design them so that you might be working with pieces that you don't even know about yet and by the way if you're familiar with the UNIX philosophy this is exactly the same the eunuchs yeah you know utility philosophy wait and in fact Li type functioning functional programming we use the types to ensure that the inputs match the outputs we make sure that you can't accidentally put the wrong kind of thing together so this is the functional tool designing things that do one thing we'll the toolkit is a very generic set of functions that you use you know as you're kind of building books so let's look at function composition here's an apple - banana function and here's a banana - cherry function and how do you glue them together how do you compose them how do you make how do you connect them well it's really obvious if they're well we track you just literally stick the two pieces together and you get any function and what's cool about this is you can't tell that this was built from smaller functions right so you now have another function that you can then use to build bigger function and so on and so forth and also what's cool is the banana has disappeared where did the banana go you know you've now got some data hiding you've got some abstraction the fact that the thing was built from small pieces which use something the bigger function can hide all that so you you know you've got this kind of nice API and you can build really big things just using functions without any classes of objects sort of thing so if you think about a web a website a website is a function there's an HTTP request comes in and it spits out an HD hears once the whole thing as a giant function it's with an input and output and when you do a function functional design inside your your main web function you have all these little little functions that do all that it'll look and they're all connect together by pipes you don't need classes you can even seriously build all right certificate applications using purely functions and if you want to call these microservices be my guest though micro-services are very similar that's the non example of a parallel composition so I have a whole talk on this if you're interested on my website all right so let's look at number one tool number one tool is mano eights okay or tool number one that's not not the number one tool is the first tool that I'm gonna be talking and there's gonna be some mathematics here so I hope this won't put you off okay if you if you're scared of mathematics then let's see so this is the first piece of mathematics and this is the second piece of mathematics and this is the third piece of mathematics so this is all the mathematics that we'll use so if you can understand this you were like so what's interesting is that mathematicians a little bit like programmers and they always like to make things abstract they're always looking for patterns so a mathematician would look at this and say mom well just interesting I can see if I can see some patterns here and let's look at this can we've got some things and we've got some way of combining them and the result is another of the same kind of thing you add two integers you get another integer back I wonder if that works or anything else oh yeah it works or multiplication too if I add if I multiply two things I'd get another thing back another integers back what else does it work for well it works with strings if I have two strings and I can catenate them I get another string back and if I have two lists and I can count Nathan I get another list back so this is actually quite a common pattern happens all over the place okay what's interesting about this pan is because when you add two things together in this case you have to introduce you get another integer you can keep going so I can add 3 to that and that gives me back another integer right and so I can add 4 to that so I can keep adding and adding and adding just like the Lego so the Lego analogy is quite good so what we have we start off with a pairwise operation like addition or multiplication or you know adding these things together and we now have an operation that works on lists we can actually extend it infinitely adding more more things without ever running out no way what about the next one if you know this is 1 plus 2 Plus 3 is the same as 1 plus 2 plus 3 ok what that means is that the order of combining the things doesn't matter if you combine 2 plus 3 first or you can find 1 plus 2 first the difference so you could do one plus two and then you could add three and then you get at four or you could do one plus 2 here and the fridge was full here and then add them later on it really doesn't made it matter which way you do it you always get the same answer so that's good now it's not always true like subtraction it doesn't work with the order does matter for subtraction subtraction doesn't fit this pattern okay what about this zero thing okay this is what is this zero mean so a mathematician will say well this is very interesting we have this very special kind of thing that when you use it to combine you know you can bind it with this other thing you always get back the original thing like the zero leaves that alone it kind of doesn't do anything it's a kind of a null pattern and it turns out that zero is quite a common thing so when you have multiplication there's a special thing that when you multiply you get the same thing back and that would be the number one and if you have strings there's a special thing that when you add it to any other string you get the same string back and that's the empty string and so on and so forth the empty list there's a zero conceptual zero for all these kinds of things it's very very common right so here's here's the pattern that we've recognized we've got a bunch of things we've got some way of combining them two at a time and that's the first rule we have is the closure rule that when you combine them you get another thing of the same type and the second rule is associativity which is when you combine them more than one thing it doesn't really matter which order you combine them in and the third thing is there's a zero or an identity element that when you combine it with the thing you get the same thing back so it like it doesn't do anything so these are kind of you know these patterns are pretty kind of obvious patterns if you start thinking about it and the mathematicians have a word for this thing they call that a mono eight so here's the mathematical jargon for something which if you just look at it from pattern analysis it's like yes it's kind of quite a common pattern that I read recognize so let's stop with the jargon Homer says no more jargon don't talk about monoids why is why is doing kind of analyzing these patents why is it useful like what how is it you as a programmer well if you think about the the closure will affect you can combine two things and get another thing that means that all powers operations can be converted into things that work on lists parents abuse start with a pair and yet out of the list and this is normally called reduce so if you have 1 + 2 + 3 + 4 you have the plus pair eyes operation and you can take a list of integers 1 2 3 4 and reduce it using + so the reduce operation all it does is basically take the list of items and stick that pairwise operation in between every single one if you have a multiplication that reduces a very common practice one of the things enough on some tools if you have a multiplication that's the pairwise operation we can then take a list of numbers and we can reduce it using multiplication alright and we can take a list of strings do the same thing rather than adding them up pairwise we can collapse the entire list of strings into a single string using the string concatenation operator and so on so forth for lists so this is a really really common pattern now the associativity the benefit of associativity there's also some things divide and conquer a parallelization incremental accumulation I'll talk about parallelization right now so parallelization means that you can take a bunch of stuff and you can spread it out over multiple CPUs on one of my machines or whatever so let's say we have to add up 1 & 2 3 & 4 we could paralyze it and say we'll do 1 + 2 on this machine and we'll do 3 + 4 this machine and then we'll take the results or add them together no ously you wouldn't do that with 4 numbers it's ridiculous but if you have a million or 10 million things to do and these are this pairwise operation is quite complicated then this is great so if you have a monoid you can instantly parallelize it now it turns out we don't normally most of us don't have to worry about parallelization but another really useful thing is incremental accumulation which is much more common so let's say the EO boss asks you to add up 1 + 2 3 because your boss your boss is no good at and she's okay and then the next day your boss says actually I've changed my mind can you add up one plus two plus D that's for today and then you say well I have to start all over again you know I just had it and now I have to go all the way back to the beginning in that one and two and four you know you don't of course you can keep the number that you calculated yesterday and just add 4 to it you don't have to add the whole thing up from the very beginning because of this associativity I've already calculated 1 + 2 + 3 which is 6 and all I have to do add 4 to it so I don't have to start from scratch I can incrementally accumulate so every time you have a monoid you can incrementally in Hulme late data and finally we have all these issues we run into how do I reduce when the list is empty how do I do a divide and conquer when one of the steps is empty how do I do incremental accumulation when I don't have any starting data and that's what the identity element is really good for it's the initial value for empty data or missing data so you have these fake things and you can anything once you see this pattern you start seeing it everywhere and you can have a missing 0 you can have patterns where there's no zero and the mathematicians got that a semigroup which is even more obscure so let's look at a real example let's say we have to do some aggregation say we have a bunch of order lines and we have to add them up and find out the total now we could write a loop and write a specialized piece of code dried them up the problem with that again is if I've again with three or four things it's not fun but if I have a million things then tomorrow I have a million the first thing I have to start I have to run the whole loop all over again you know so let's use the monoid idea because that gives us best of bullet over all possibilities so rather than trying to write a loop what I'm going to do is say well you know integers are mono AIDS floats amides any combination of a mind as another money so all the line is a moment and all I have to do is write a pairwise combiner where I just add the two pieces and return the new thing so I have a pair wires combiner which is normally pretty straightforward to write and then once I've got the pairwise combiner I can run it on the entire list just reduce the entire list using the pairwise combiner so there you go that's there's really there's a pattern it would be useful not to say if I have another order line come in tomorrow I don't have to recount the entire total them swatch I can just add this extra one by using the incremental accumulation principle profit now a lot of situations you don't have mono s so for example I have a bunch of customers and I want to find out how you know at let's say I keep track of how many times they visit my website how much money they spend or whatever I'd like to add all that stuff up but I can't because customers are not mano eights however I could create a special kind of class or a structure called customer statistics which is just integers and stuff and that would be a mono because it's all kind of numbers so what they typically do is you take something which isn't a ma night and you turn it into something which is a mano it's and once you've got it as a monoid you can then reduce it down so good turning something which isn't in a model it in term honor that's Mac and then clapping the whole thing down into a single values reduce and you've probably heard of MapReduce but MapReduce out with them so that's why it's called MapReduce it's something to do its moist so here is a nice treat I saw a long long time ago how'd it make me a sandwich so how do you 'pizza is it just you know it does parallel computation and you start off with let's say you start off with some bread and some lettuce and whatever and onion or whatever you can't just mush them together and make a sandwich right they're not they're not composable they're not mono it's but if I slice the loaf and I slice the onion I slice the lettuce the slices can be composed into sandwiches so you know you can then reduce the the slices interest intercessor session of sandwiches so this is mapping followed by reduce as a way of you know making sandwiches so it's kind of fun right here's the problem with monoids is once you recognize this pattern you start seeing in everywhere for example if you do devops or something and you need to keep track of six there's a little rule saying use counters rather than rates and if you say if you're into mono age you say just make sure you metrics the moloids because you can do incremental updates and you can handle missing data Renaissance art and in fact many many design patterns are actually mono is behind the scenes Marc seaman just wrote a blog post the other day about this things like the composite pattern is a mono it the null object hand is a mono composing commands together to make a new command is a mono it and if you're into DVD in the DVD book it talks about closure of operations that's the mod so you really start you know it really kind of wounds you actually now you say well why use the word monoid there's a jargon your word but just like any piece of jargon once you know what it means it's a shortcut to explaining something quite complicated so if I say to somebody else and I say this is a monoid and they know what that means assuming they know what that means they will instantly know that they can paralyze it but they can do incremental stuff that it has a zero element you know all these kinds of things so it's a it's a great shortcut for explaining you know a company and they also know watch patterns to use how to work with them straightaway what about a functional composition is that a monoid so here's an app you know whose are two functions and we compose them together and we make this Apple to carry function it's not the same kind of thing the Apple the you know one thing is an apple - banana function the other is an apple - cherry function so composing functions there is not really a male - unfortunately but if we have functions that turn apples into apples and we combine them we get another function which turns apples and apples and that is a monoid because it's exactly the input functions and the output function is the same kind of thing so if you're working with functions that turn integers into integers or strings into strings that those kinds of things you can actually do them incrementally you can do them you know whatever all that kind of stuff because they're wrong weights right so that's everything you know about mermaids a set of values a combining function and it has also such words even if this is what I say so pattern you couldn't recognize because the actual word that he used with an abiding function could be anything so for Strings or lists it's it's not the golfing cat for an integer Zitz called plus in Haskell is the angle bracket sometimes and sometimes you see a platino you're plus all sorts of weird symbols and things but it's the same concepts everywhere and this combination the combiner has to be closed associative and zero so here you can use it for reducing a list you can use it to do parallel computation you can use it for doing incremental calculations all this stuff so there you go that's a monoid so that's tool number one hopefully my nodes are not quite as scary now all right as demystified a little bit I hope now we're going to go even more scarier but and talk about effects so what is an effect functional programmers talk about effects all the time so effect is really just a generic type like a list a list of something or it could be a type with some extra data in it like an option type or a result type it could be a type that changes the state of the world like in a sink or it interacts with the world you know tars random number generators or it could carry state around like a state type of cars or type it can be all sorts of state it's actually kind of vague one effect is it really could be all sorts of stuff it's basically you know really it's just a generic type person you know generic type is is is a normal type with some extra stuff right so I'm going to focus on three types in this talk to use them as examples list an option and a sink so hopefully everyone knows what list is the option type if you're using Java this no not there's an optional stuff built in hopefully is most people are familiar with the optional type of some kind and the async type is it you can think of it's like the task type it's kind of similar f-sharp uses a sink and then C shop uses tasks so this whole thing of effects there's like normal world and effects world okay so in normal world you have strings and you have integers and you have billions anyhow functions the turn strings in the instance of strings you have function of the turn into bills so this is like your normal world of the normal everyday objects now what's interesting is for every kind of effect type like options unless normally there's a parallel world it's like a mirror world and everything in this world is options for example so instead of having strings you have optional strings instead of into your options and optional books and every function that turns an instant of string in optional world that function turns optional innocent optional strings or it turns optional in sins are optional bills all right so it's like a parallel universe and same thing with lists worlds in list worlds everything is lists of things there's a list of strings and lists events and this the billions and all the functions turn lists into lists you know so this is mindful analogy for these worlds and it's going to be quite an important concept we're going to be talking about these worlds quite a lot and async is another world everything you can see how it's going right you can see the pattern here and so there's this called generic effect no matter what effect it is there's some sort of e I'm going to call Eve a generic effect and there's generic effect types and a generic effect functions okay so that's my effects world so that's the that's everything you need to know about effects just remember every time you hear someone talk about effects you can probably replace it with option or list or a sink or whatever so here's here's our first problem is how do we work with these effects we need to do stuff in the effects world sometimes and how do we do that and I'll give you a some concrete examples so let's say here's the world of normal values and here's the world of options and sometimes we have a function that takes us from the world from the normal world into optional world and then we need to work with the data in the option so we then basically extract that data and we do something with it and then somehow it goes back up into optional world again and then we extract the data again and it goes back into optional world this back and forth between worlds is a really common pattern it's actually really bad and so like don't do this all right functional progress which would call this a kind of design smell or code smell so like well you know how could how do you solve that right what you really want to do is when you go into the effects world whatever it is you want to stay there you want us to keep working up there and only come down at the very end if you have to I mean a good example in c-sharp is the task or the async/await once you've made something async or you turn into your basically stuff you let you have to everything else has to work in that world in the async world or the task world and you only ever come down at the very top of your program you don't you know it's bad bad practice to like a wait for a task to finish and then start another task than to wait for the side what you want to do is lift everything up into this async world and work up there and then at the very end of your program which is you all can fall or whatever it is that's where you actually deal with the async or the task so that's the right way to do so let's say we have an ad for to function very important function and if we went on a normal thing like 1 we get the answer 43 if we were not on another thing which is an option world like someone it doesn't work it only works on normal things doesn't work on options so this ad 42 function is useless as that by the way it's dance so we say ok well let's write our own custom ad 42 - option function so we say well if the option is something if it's about it then we're gonna you know run the ad 42 and then we have to wrap it back up into option world again and if it was never something then we're done we don't have to do anything so we're we're unwrapping it we're doing the thing that we need to do and then wrapping a break up again and that's like I say that's a bad way to do it you're going down you're doing something you come back up this is an antique man so what you instead you want to do is you want to somehow be able to work with this ad 42 function up in the effects world in the optional world so we want to stay up there so how do we how do we how do we make an ad 42 function up there without having to the only special thermal every single time and that's what mapped us so this map is a there's a function transformer that moves functions from one world to another Wells so if we have a function down here that turns T's into use if we do option map it turns options of cheese into options of use that's what option that does so in our code instead of you know with our normal function we can say option map around 42 and that gives us our and 42 to option so now we have a the add 42 now works in the world of options and we can run it straight away so we now have a function in the option where we didn't have to write any special code to wrap it and unwrap it again it just happens for free and typically we don't actually write a special we don't give it a special name we digitally inline it like this the option out of this and we can apply it to the other thing same thing with this world let's say we want to add 42 to each integer each item in the list so you know for each item in the list we had 42 and then we put it back in the list again and return the new list say but we're doing this thing when you're doing an iteration you're basically unwrapping things out of the list you're pulling out each element out one at a time applying the thing and then putting them back in a list again so again this has been a dependent you don't want to come down do the thing and go back up don't do that again we can instead we use lists map so it takes a normal function down a normal world you run list map and it gives you a function up in list world so if I wanted to find the add 42 to each function all I have to say is list map of the add 42 function now I have a function that works on this I didn't have to write any special code so that's kind of cool so you can see that this map is really really useful and people say well I can always write my own loops why is this any easier than writing my own loops and the answer is that again if you if once you know what this map does first of all it's easy for you to use because you don't have to write any code secondly it's also easier for someone else to understand assuming they understand how how it works they can look at your code and they know exactly what's going on sometimes if you look at a complicated loop you're trying to figure out what's actually going on in this loop you know because it's not the loop logic kind of gets in the way of the actual thing that you're trying to do if you use things like this map the loop logic it's kind of hidden so you can really focus on what's actually being transformed what's actually going in this case it's really obvious that we're adding 42 to each item now if I had a head of loop and there was like 42 in there it would take me some time to figure it out so I actually think this is better once you understand what this map does it's actually easier and of course async same thing we have a normal function and we can map it into the world at resync and that way we can kind of chain async function together so most generic types have a map there's no single zone you use them and if you are your own generic type that you're going to put out in a library make your own map and then everyone else can use it and of course now we have the jargon version of Mac so the jargon version is it's a funk guitar so a function is an effect type which again is option nor a single list or one or whatever it is plus some sort of map function that works with it there's specifically designed so you know the definition the implementation of map for options is different from the implementation of map for lists which is different from the implementation of map for tasks or you think whatever but the concept is the same so I can use in a list map or whatever once I know that this thing is this I know exactly how to use it the map function has all sorts of different names sometimes it's called selects sometimes called lifts sometimes it's called f map so it needs to have a sensible implementation it turns out there's a bunch of things called a functor laws which is really just a fancy name for some rules that implementations should have to make sure that they work sensibly like you thought you shouldn't do them something too stupid and the function laws are just basically a way of making sure that your implementation makes sense so that's number two what about number three well this is a really simple one this is just sometimes you know we just talked about moving functions from one world to another let's talk about moving individual values like integers or strings and that's called the turn so here a word of normal values and we want to make it an optional int we just use return right here it is and here's a normal value and we make it an optional int or lacking something similarly with lists if we are a single integer and we want to make a list out of it we use lists return and that makes a list events so here you have 42 and we make a list out of it you know just in this case it's really easy it's just tonight single item in our lists so again it's not normally called return I mean the actual way of making these things that the name is all sorts of it's all different in different environment the concept is you're just moving thing from one world to another value normal world value in this world so you bear with me you probably thinking all these things are they actually you know useful and at the very end of the talk I'm actually going to show you how to assemble all in a real piece of code using all the different tools together and you so just think about how you know how these tools can work together to build a complex program now this is the most important tool probably in the function problems which is bind and it's it's is used for world crossing functions I think what they it's a world crossing function okay I know introducing all these kind of concepts but they're not they're not some particularly difficult to understand I don't think it's just something different that you're not used to if you you know on a functional program so here's a function called range and you give it a maximum number and it will give you a list of all the numbers up to that number so if you give it a you know the maximum of 100 it give you all the numbers from 1 to 100 okay pretty straightforward now if you look at the what it does you pass in an int and you get back a list events right so you have a value in normal world and the output is a value list the world this is really really common so if you think about it like this you start off with an int down here and you end up with the list of ends up here I mean this is range now here's another more complicated example let's say you're getting a customer from a database are you passing the customer ID if the customer is found then you can say yeah I found some customer data and I'm going to give it back to you if I didn't find the customer I say okay I won't give you back anything and again if you look at the inputs and outputs for the function it says will you give me a customer ID which is a normal thing and I'll give you an optional piece of customer data so the the input is in normal world but the output is an option world so again this is a world crossing function it starts down at the bottom and ends up at the top these functions are really really common in functional programming so the cases that get customer function so this is like really really really really common problem and how do you change these things together so here's some code it's just it's kind of silly in this example you have you do something and you get back an X and let's say that do something is a world crossing function it returns an option say well I can't really do anything with the X unless I know whether it's valid or not so I have to say is it something if it's something let me go on and then I do something with that and that maybe that gives me another something and I have to say I have to check that as well and maybe then only when it's valid can I do the next thing and I have to check that as well and only when it's rylynn can I get the next thing and so on now you could replace this with null checking you probably seen the same kind of code if it's not now do the next thing if that's not no I'll do the next thing you know if that's not null do the next thing so this is just the the option version exactly the same code and it's this horrible thing you get this massive thing you've got all these nested checks and they and they add up they get if you get more more indentation in your code and this is typically called the pyramid of Doom because you're you know as you if you have like three checks it's already pretty until you have 20 checks it's gonna be you know it's just ridiculous you wouldn't want this is just horrible code nobody wants to code like this and you see this all the time in other situations let's say we're doing with guitar and we went a task and then when the task is finished we get the rally that gets output and we run the next task with that and then when that task was finished we do the next thing and when that's finished we did the next thing so whether these are tasks or promises or futures whatever you wanna call them you see this pattern a lot - and again it's a pyramid of doom you can have a world crossing function you always have to check you always have to kind of deconstruct it you have these nested two callbacks in this case and you end up with this pyramid so this is ugly no matter what it is so let's see if we can solve this problem let's fix this there's a pattern here that we can exploit you might see if it's something do something if it's something do something if it's something do something this is the pan so let's turn that intraductal helper function okay we're going to say if it's something do something and if it's not then we do nothing that's the pattern so what exactly we do we don't know what we're going to do with that thing so let's parameterize it we're going to say we'll pass in a function parameter and the function parameter will do what we want to do we don't have to worry about what it is exactly so we might a piece a little a piece of code like this if something do and if it's if the if the input is optional then we run this with a helper function and if it's not though it's missing so this parameter this function parameter is the things that you want to do as the next step if you valid so once we have this little helper function we can rewrite our original code to look like this do something and if it's something then do the next thing and if this if that one isn't something then do the next thing and in fact something do the next thing and this what this little helper function does is basically clean up all that nested stuff we now have a nice linear vertical-align thing there's no indentation going on so this is a really really nice way of tidying up your code how I'm going to use the railway analogy so with options you can sort of think of there's an input and there's two kind of two possible outputs there's either something or it's nothing and if it's something we want to do the next thing in the chain and if it's nothing we want to bypass right so if you actually had little bits of railway like if you're playing with Brio or wouldn't wouldn't well we have some kind how would you connect these things together well you couldn't connect them like that but you could connect them like that so this is this is you know this is very close to what we want but if we can get something like this then we've connected more together very nicely so that's our goal now here's the problem if we have one track functions with one input and one output they're easy to compose we just connect the inputs and outputs if we have to track functions with two inputs and two outputs they're also easy to compose we just want them up in the obvious way but what we have is one track input and to track output and those things cannot be composed they just they don't fit together properly so how can we combine mismatched functions like this and the answer is bind bind all things functional programmers love the word bind so here we are here's our problem again we've got these kind of points that don't compose if we had to track functions they would compose those are good so how do we get from before to after okay well we have a function adapter a function transformer and if you think about the wooden railway track you can actually get these kind of little wooden adapter blocks that you stick in you know so you know you put in this in this adapter block you stick in your your points function and it comes down as a two track function and that's at RSA it's a kind of function transforming functions as input and functions as output and the implementation it's it's big SMO you know it's actually a very simple impression it's like literally four lines of code it's more complicated to explain and then to actually show the code so here's the code an input comes in and if it's something we do the next function we do the thing that you pass in and if it's nothing we don't know anything so that's actually the entire implementation of bind for these kinds of points functions so if we use it for training options this is what it looks like before if we use up a chain for doing you know we write this in a bind helper function by the way is exactly that little if something do function that's exactly the same so that if something do is actually buying the same thing again it's got this parameter that you pass in as the next thing in the chain and then our code then becomes linear so we're now using bind as look as the word here so no pyramids and it's linear and clean and if we do the same thing with tasks when a task completes we do the next thing in the task and if it doesn't complete whatever we don't do the next thing same kind of pattern we write little task bind insert okay so this is the ugly version with the pyramids of doom and we added a task bind which again is no it's a different implementation but it has the same concept it's like chaining tasks together when we get the result we want to run a function on it okay there's a little what is our parameterised next function and then once we have something like this we can then whoops we can then connect all the the tasks together in a linear way we can you know start a task and then we can bind that to the next task and we can bind that to the next task of buying that to the next task so this is the it's as I said my as a general concept it's not just specifically for options on this sort of tarsus a concept you can apply to almost anything to any kind of effect and let's look at one more example which is error handling so here's an example of a function that doesn't narrow handling you receive a request you validate requests you might canonicalize the email maybe make sure it makes make sure it's a lower case you might update the database you might send an email to the customer or something who knows but this is pretty you know it's only five lines of code is pretty straightforward but here's the problem errors happen like what happens if the request is not valid what happens if the customer isn't found in the database what happens if you get a database exception what happens if the SMTP server doesn't send email you know all of a sudden you start off with a bunch of simple code and also in your code gets really complicated in this case it's three times longer or twice as twice as long as those and this is you know if you've written our handling code this you see this all the time you start over something which it starts off really simple and it gets kind of cluttered and complicated and messy and and you lose track of what the important features are the important stuff is is buried in all error handling so let's look at the functional equivalents we're going to define a result type which basically is two choices it's got a success case an okay case and an error case or a failure case and it's one of these points functions again something comes in and it can either come out as a success or come out as a failure and then all our little validation functions basically say in this case if it's if the name is blank as an error if the emails blank that's an error if they otherwise it's fine and you go through all the all your functions in your workflow you do the exactly same thing and you end up with a bunch of points functions like this validating might might not return an error updating a database my oh my oh my oh my not return there are sending an email might be an error or whatever again you have exactly the same situation here before we have these points functions and we want to connect them together and there we go we're done so that's the two-track model of error handling otherwise known as a railway order programming and I have a whole talk on that if you're interested so here's the here's the code before we added error handling let's say we don't do any Harry handle we just throw exceptions right so we take the request we validate it we do all the stuff it's nice and clean but there's no error handling right because maybe a one track now if we add the error handling in let's see how much more complicated it makes it okay we're going to do a lot of error handy now every single thing's gonna be handled nicely so afterwards this is what it looks like alright it looks exactly the same now I'm cheating a little bit because I'm using this exactly the same names of the functions but I could validate requests where they were handling an archive email with error handling your update DB were there anything you could name the function slightly differently but the point is you still get this nice workflow but behind the scenes in the two tracks you're handling all the errors really nicely this is a very nice because it keeps the keeps the coke clean right so binds and C is really important the reason it's important as it makes world crossing function is composable so let's make now let's take bind and just make it very generic to any kind of effect they could ever think of it's because it's a pattern really this is a conceptual way of thinking about props we have these world crossing functions which starts off in normal worlds and it ends up in the world of effects so this is a kind of a diagonal function you're going diagonally from one world to another and the problem with these things is they're not composable right now what bind does is it turns it into something where the entire function lives in the world of effects so it's a horizontal function so you've turned a diagonal function into a horizontal function now these horizontal functions are great because they're easy to compose you can literally just glue them together so let's look at example of that so let's say you have a bunch of diagonal functions like this right you take like say you can't glue them together they just don't work doesn't work but if you use bind and you turn it into a horizontal function like this and bind again now we have a bunch of horizontal functions and they can all be glued together so this is why by just so important it's a way of chaining together diagonal functions and diagonal functions are functions they happen all the time whenever you whenever effects happen every time you you know you you work with the i/o whether you worth a database whether you work with options or errors or results or this whether this happens a lot so that's why i buyed are so nice that's the right way to do it so back to some terminology again now we know what a monad is so a monad is an effect type of whatever kind you want to call it like option or list or anything from the same whatever it does really doesn't matter what it is plus of a turn function it turns normal values into the things well that's trivial you do you underst they were and return is sometimes called pure sometimes goal unit there's lots of names right now here's the key thing there's a bind function that converts the diagonal function into a horizontal function so this is you have these three things and of course people are inconsistent with the naming my programmers always are some people call it bind some people call it Mac Mac in Haskell they don't even have a name for it is just as funny symbol with two angle brackets in c-sharp if you use link select many is a bind operation and you have to have sensible implementations and those are the Monad laws so when you hear something like the Monad laws you know if you break the Monad laws you're going to go to jail no if you break the Monad laws it just means that your your code doesn't work the way people would expect because you're not the implementation doesn't it doesn't make any sense so that's what a monad is a monad is there's these things it's just that a type plus two functions plus some rules you have to follow when you implement it so hopefully it's not so scary maybe maybe monad a little little bit demystified okay so monads are so important because you have these effect generating functions you want to chain them in series you need to use a monad now one quick thing is mono is versus mono AIDS and this sounds like the same words they are efficiency they actually different but there's a there is a connection because there's another way of composing these points functions you can compose two points functions get back another points function it's the same kind of thing and there's there's a symbol for that kind of thing angle bracket equals angle bracket what's interesting is if you combine these two things you get back another thing at the same type does that sound familiar so you can repeat it repeatedly add things to them and it also turns out that the order that you can buy things doesn't matter so this looks awfully familiar and in fact if you do this this kind of composition is in fact I'm already using points functions right enough of that one more thing and then we're talking lives so we have these effects like we have an option of something and on that option something will you combine them so get a pair so let's say we have an optional 42 and an optional hello and we can find them when we get a pair you know an optional 42 and hello as a pair as a tuple which is affecting what you expect now if one of the things is nothing then the overall result is nothing all right that's also what you'd expect now what about lists if we combine two lists and we create a pair of item pair of items from each lists how do you do that well it turns out there's actually two different ways one is the cross product so if I have 1 2 3 and ABC I can pair each one with every other one so one at a and then one being on C and 2a or 2b and 2c and so on so there's nine possible answers the other alternative is zip when you zip to this together you just take them pairwise first one in the first one 1a and 2 B and 3c so there's two different ways of combining lists the general term the combining things like this is a picutre functor another another kind of nasty word and optional s an async electives pretty much everything you're going to run into can be treated as an objective so a package functors that's a horrible name really isn't it again it's one of these effect types plus of a turn function plus some way of combining these two effects into one and it's got all again also sort of names apply pair different slightly different implementations exactly how it works but the whole point is you're basically combining things and again there has to be sensible implementations which it calls a functor applicator functor laws and so on all right why is this useful it sounds kind of interesting but it's actually relevant well here's a here's a really common problem you want to validate field in parallel let's say we have a customer and they have to have you know the name has to be 50 characters exactly or less than 50 characters it can't reward the email address has to be validated being outside that you know it has to be proper birthdate which is more than 19 less than the Hyundai whatever often you have these validation rules so we complete some validation functions just like our points functions that we've done before but when you chain them together the problem is if there's an error we get the first error and then the rest of them are bypassed so we get one error and all the other possible errors we never even know about so you know that's okay but it'd be nice if you get all the errors at once right that would be nice so what you do is you say you start off with a piece of JSON or a little you know the DTO toy where nothing is about it the string could be anything in the email could be anything for each field in this data structure you won the little validation rule and you get back some results and then you combine the output to make a final sign that way you get to keep all the errors at once that's what we want to basically run this stuff in parallel rather than in series so how do we combine them that's where the applicative comes in so we have all these different values which live in result world we have a result of a name it might or might not be valid we have a result of an email that might or might not be valid and a birthday that might or might not be valid how do we combine them well we don't have to combine them in the normal world if we have a valid name and a valid email and so on we just use the constructor to combine them right we can we use the constructor and we now get a van a customer but this is working in normal world what's cool about applicatives is that you can turn a function that works in normal worlds into a function that works in result world so you can take that constructor function and kind of lift it up into result worlds using the magic of applicatives I'm not going to tell you how to do it because it's kind of confusing but the point is you can take these individual things and make a customer and this customer is in result world and it's done in parallel so if there's any errors all the errors are combined so if you look at the code for this here's creating a valid customer in result worlds we do you know is that validate the one thing the other thing we get the name or an area it's not necessarily a valid name it could be a name or an error right now that constructor is the normal constructor but we use these magic symbols here with the angle brackets and we call it just like with a different just like we've called the normal constructor but we use the magic symbols instead of just a normal function call and this is magic and the output means that we get this error message here's the magic symbols and not that explain how they work but the cool thing is that everything works just like you're calling a normal function now notice that we get a list of error messages how do we combine the list of our messages combining two lists to make another lists we're using monoids so we're using applicative nanoids in this example alright let's review the tools we've got combined which combines two values we got reduce which reduces a list we have map which lifts functions up we have return which lifts individual values up we have bind which turn this diagonal functions into horizontal functions we have apply which combines things in parallel and there's other words for that you might see lifts and so on right let's look at an example I think I'm running a little bit late I'll just be another couple of minutes let's use all the tools together so let's say that you need to download at a URL into a JSON file and then you need to parse that jason interest for example a customer dto and then you need to turn that DTO intervallic customer and then you need to store that customer in their database okay now we all got these different worlds going to be working with when we download the JSON file we start off with the URL in the normal world as a string and we actually end up in async world's an async world which is on top of the result world so when you download it it could be a valid piece of JSON or it could be an error because the server didn't was one and the whole thing is async because it doesn't response right away so we've got an async of a result of a piece of jason okay that's our first function the next function we take that piece of jason and we parse it when we decode it into the customer DTO but that might fail because the Jason's invalid right okay so that's it could be an error and then we take the customer DTO and we take out the three fields and each one of these might on my got a valid and then we take those three fields and we can make a customer and then we take that customer in normal world and we store it in a database which again it might or might not still properly and it might be asynchronous so we have all these functions and how we're going to compose them together they're all diagonal functions all weird shapes they're just not going to be composed together none of the stuff matches up but luckily we can use our functional toolkit which we know how to use so the first thing is we have these parsing thing and then creating the customer we just saw had to do that with the applicatives so we can actually replace that with a function that turns the DTO into a customer okay so we've got a DT oh and a customer now where does the DTO come from it comes from parsing the JSON but when we parse the JSON we don't get a DT oh we got a detail or possible error so it's not compatible we have these diagonal functions well how do we do that we use bind okay we do bind on these two functions and now we get some horizontal functions which we can then connect together we compose them together into one function which now takes Jason and turns it into a customer and then here's the code for doing that we have a JSON or error we bind the first thing we bind the second thing so they're literally the code is tiny okay the problem with this is it's still in result well we need to move it into a sink worlds so we use Mac and now it lives in async will and then that's last one storing a customer is again it's a diagonal function so we're going to use bind on it again to turn it horizontal right and now we have the first one goes up to async worlds so Jason to customer is now all in async worlds the customer to storing a database is also an async world so these are now all exactly the same types we can glue them together and make one single function that goes all the way from one to the other so there's an example of how you'd use these tool that you use to this toolkit so here's the code again but to download install custom we start with ul we download the file we take the process thing we just defined and map it up and then we use bind on the last one to wrap it up so again just a few lines of codes it really takes a lot longer to explain everything than to actually write the code you could write this code in mini R - yeah so but we're using the same tools I'm using different kinds of tools that the concepts are the same all the way through so just one thing to take away even if you don't understand everything which I don't think you cross that we can the jargon is jargon just like any kind of joking but it's not that scary you know you can it's just unfamiliar and hopefully you can see one functional people go on about monads all the time right now this is a very generic toolkit they've got a set of functions like Mack and bind that work for anything it's a set of patterns this is really the equivalent of the pattern language just like used to strategy pattern and factory pattern and so on this is the kind of equivalent pattern language for functional programming so we use these consequences over and over and we just sort of use whole bunch of them just for this one is example hopefully you can now see when you see map and apply and bind use you'll have some idea of what they're for but like I say I wouldn't expect you to understand them or it takes a while to get used to them so there's the functional programming toolkit I'm going to post the slides up on my website if you're interested in this I've got other talks I've got a whole thing on design patterns I've got a whole thing on composition the whole thing under main modeling I have a whole book on domain modeling if you were into that follow me on Twitter if you're interested and otherwise thanks so much for coming [Applause] I feel free to ask me questions I'll be around all day
Up Next

Functional Programming Design Patterns Explained
@ivanplyusnin3292
199.1K views•2015-08-30

BitTorrent Protocol Explained: Piece Selection & Peer Choking
@StevenGordonAU
481 views•2013-02-22

Thinking Outside the Synchronization Quadrant | Kevlin Henney
@NDC
31.5K views•2017-02-27

Enigma Machine Mechanics: WWII Encryption Explained
@JaredOwen
13.2M views•2021-12-11
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Computer Science





































