 How many of you have gone through the note about the talk what it is? Okay, at least half of you, okay, good. Yeah, so we will talk about that. So that is about me, I think we come in the recording. So some prerequisites like the other assumptions that I made, are you all aware of the basic function FU principles? Probably the first few days when we learned. With the Haskell syntax, I think in the previous talk, we have seen some types being defined and something like that, okay. And curiosity or breaking of the initial shell, for example, how many of you tried, started using probably map, filter, flat maps, all those avoided loops, but then stopped right there, okay. And trying to go, understand what is next, right. So if you already understood then probably it is not needed, but if you are in that stage, I think it might help. So let us talk about M, whoever has gone through the note knows what it is. It is monads, but we will talk through it, we will talk about monads, we will go to that route via functions and applicators, applicators. So I do not intend to present any mathematical definitions because that is all over the documentations, internet. So this is about, I want to share about how I tried to understand what they are and probably what I thought, you know, I did not find an explanation like that anywhere else. So if you are, if there are experts, you are probably at, if there are anything missing, let me know. But we will understand it in a slightly different way. So what initially the first principles, right? So there is only one principle that is all about the functions, like what is the solution is a function. So let us go through some transformations. So I will take an example, like if you have a user and find a user name, right, so that is some password code, like essentially you get name from the user, name of a user. But what if you have to do for a bunch of users, right? So you have a list of users, you want to get those users name. Can you still use the same function? I think you know that no, yeah. But what is the solution? Stream, yeah, Java, you do that. Stream and what do you do next is what I am asking, like you convert to stream. Okay, so essentially the question is use another function. So most of the answer is use a function. So it is using another function. And that is fmap. You give this function, give the list of users and you get list of names, right? That is all of you would have done it. Now comes the different part. What does fmap do in this case? Can you explain what does it do? Exactly, exactly, exactly. That is how we learnt it first. That is apply this function to each element of that list of users, right? And you get the name. Fine. It kind of very easy to understand, goes well with what we have been doing until now. But is there any other way to look at it? Yeah, that, okay. So again the thought process is you have this function which works on the individual element. So you take out from the container, apply this and then, okay, any other way of thinking through it. Let us see whether we have something. So let us move that to the side. Think about this. So you have this original fmap down here and you, can you convert that on to a function which you can apply it on list of users? So essentially if you pass on your first parameter, it is like you lift a function which works on individual user and gives the individual name. You lift that function to something which works on the list of users to list of them. So this, if you start understanding this in this way, then we can nicely graduate to the next two levels and reach, understand one of the property of the code property of the monad. Does it make sense? Exactly. So the way we look at it is yeah, all I need is functions for solving it. So I need a function which will take in a list of users and give me a list of names. Now how do I create that function? So you, to fmap, you pass your ordinary function which works on user and gives the name and it gives you f another function which works on a list of users and list of names. So that's key difference. I mean it's, at the end of the day, it does the same thing, but the way you understand, I mean this is one of the ways to understand, that's another way. That's more easy, that's more, the first thing how you understand is that, then you, in fact, if you're doing Scala or Java, probably you understand on that. When you come to Haskell and apply only partial, do a partial application in the new real area, what I'm getting is another function if I don't apply the other two, right? So now we come to, let's look at some circles and squares. So we have the thing which is represented here using that yellow circle and we have the thing which holds that thing. It's a container, it's a context which holds that thing around. And this thing has a function which takes in two normal values, taking a normal circle and converts it to a square. And it gives you another function which will take in a circle which is embedded in a square and then gives you a square, I mean, yeah, green square embedded in black square, whatever. So this is what we saw. So this is fmap. So that this was a list, in our case, this contained a user and we had a function which user can give a name. We gave it to fmap, fmap gave you another function which takes a list of user and a list of, does it make sense? Yeah, exactly. It gave name of user. So this, the blue color is fmap. Yeah, I mean fmap, what is fmap taking? fmap is taking this function, user to name, and it gave you another function. This function is name of user. The top, yeah, which takes in a, yeah. So in this way it's generic, like, you know, that user was a specific example. It could be anything. Yeah. So then that contained, that means if a container has a function, in this case it's named fmap, which takes in normal function which operates on the constituents and gives you back a wrapped, you know, function which takes in a wrapped entities. Okay, this is fmap. Similar principle you can apply. So next one we'll see. So in this case it's a different function. So now it takes in a function which is wrapped in the same context. And it gives you the same thing. If you think about the previous example, it's like, assume you had a list which contained the function user to name. Now that's all you have. Now, but my, I want to operate on list of users and give you list of names. So this, this, this is what that does. And that's applicative, applying, I don't know what to call it. AP or that we are looking simple in Haskell. I'll, I'll, I'll have an example. So these examples are all combinations. Like you do a system map and then you end up in a situation where you have a function in a container and you need to apply that. So that's, that's all typically. Is that clear? All right. So now go to the next one. So this again, it's another function. So here, so what is the input? The input is a normal stuff. It takes the same example. It's a user, but it gives you a list of names. Let's say the user has multiple names or last name or alia formula. Let's assume that you have multiple names. Can you guess what's the, what's the function that it gives out? What's the output? It's, it's not been changing for the last couple of times. So that's only the input which changes. And this is essentially your variation of bind because I tweak the parameters around the bind to have the story we did. So, but the actual function is that. Right? So this, this, this are the three things. First, you have a function which takes the normal user to name and gives you back another function which runs on list of users or list of names. The second is you, your input is a list which contains a function user to name and you get the same function output. Third is you have a function which takes the user, gives a list of names, but then the output is you have a list of users and list of names. The list, if you are using Scala, this is the flat map. All right. So now you look at it. So, so you have, this is the first one. So you have a fmap or less than dollar grade one in Haskell. Takes a function, gives that, and then there is another property where I think Tony had that type if you are in the session, like to give a type A, container of B, you replace B with A and use the input. So that is the second one. If these two functions are the, these two functions are defined, it is a function. So you can, for understanding purpose, you can ignore the second part. The one which is not used to map is a function. Now we will expand on, we will bring the other one. That is kind of tilted. So you have a applicative stuff, that function or AP function and you have a way to create that container. Something you give in the same example, you give A and you get a list of here. You give A, you get a maybe of A. You have a way to create it. It is called pure. This is applicative function. Somebody, some entity which has all these functions and then comes our bind or flat map operation. It has a return which is same as pure. Okay. Everything you will have seen is rather, rather laws that these have to satisfy. There are other various functions which are defined on these type classes. But this is the code. So how, so the point I wanted to convey is another way of understanding is like how what kind of function transformation it can do. Like take A to B, gives me a function which works on, let's say MA to MB takes M of A to B and gives me, let me back a function, M of A to M of B. Take a function A to M of B and then transform that to another function which takes in MA and gives me. So that's the three stages. Is that complicated? Like how is it? Yeah. Yeah. So yeah, anything in monad is not completed without talking about bind or what that's at least used for. Let's look at this. So this is the function which I defined where you take the first parameter is a function. So that if you do a partial application, you get another function. But actual bind operation syntax is different one. The first parameter is the actual container. In this case, it can be a list of user and second is a function in third list of things. So what bind enables is I think you explained it. It takes the value out of that container and then creates a second one out of it. So you can chain multiple, let's say if you have maybe you can chain multiple, maybe it's multiple lists, whatever the container is. But one condition, the container has to be same. You can chain maybes. You cannot chain maybe you have replaced or it has to be list or it has to be, in this example it has to be always a black square. You can't do anything else. That's what you can chain. And other significant stuff, if you are, eventually, if some of you have already reached this stage, other things are monoid transformers, that is when you have to chain multiple types of monoids. I'm not going to talk about that for the next stuff that you need to even read about and try doing it. Alright, so this is the summary. So this is kind of half of the talk actually. I could have just shown this one slide but I wanted to build it out gradually. So this shows everything. So you have the first one which is counter, second one applicative and third is a monoid plus other one. I'll just leave it for a few seconds. Any questions? You can just see this and if any of the things are not clear or something is confusing, let me know and there is a, I think there is a problem or the monoid maybes, maybe I have to correct it. Exactly. Yeah, that's one property as output remains same. It just was, so these three are the different things. The kind of input. Alright. So look at some examples. Again, examples of the existing monoids. One is maybe, how many of you used maybe or collection or option? Java is an option. So let's look at a similar example. Let's say we want to create a greeting for a user based on a user's alias. Let's say it's used in an environment where you want to reveal the user's name. So alias may or may not have been configured. So in this case you are mapping a function. Given an alias, it will say hello given a name, hello John, hello X, Y, Z, hello does that make sense? Like it's taking the function and then giving the alias. Now we can do the same using applicative. So this I would like to explain. If you see the first part that is it's mapping this append operation plus plus operator on just of a hello. Like hello is the constant string that you want to be prefixing with. So in this what you have is you have a just which contains a function. If it takes one more string then it will give you that hello space that string. Which takes an alias. So now you are in a situation where you have a function inside a maybe. If you have a function inside a maybe, what you can do is the second one. So you have a function inside a maybe. So you need to use the AP function. So that's what is that less than A to N star. And you give the alias and you have the same output. It's a function. It could be function which could return another function. It could be any kind of function. But it has to be A to B. Or A to A whatever. It box could be anything. It could be list. It could be anything else. Yeah, correct, correct, correct. Exactly, yes, correct. Plus plus is a two argument. Everything is a one single argument function. But let's you can understand it. It has a two argument function but applied only one. So it will give me another function which takes the next argument whenever it is available and it will give the value. Sure. So the black box in this case is maybe. Okay. So when you fmap plus plus over a value or just hello, what you get is a maybe which contains a function which takes the actual user's alias and give you back the string hello user name or hello user alias. So this, so black box is maybe that's a function which takes a string and another string. In that case the types are same. Like both are string. All right. So now the next one. So this again I picked an example in this case just to show all of the same user, same model like user and the name. So let's say in this case the user has a invalid character. Like your system cannot support certain characters in the alias. Like I want to find out what those characters are. So in this case you have a function so here and it returns you a maybe of an may, such characters may exist or may not exist. If it exists it will give you just whatever number 2, 3. I know that you can do it within just 0 but let's ignore 0 for this part. If no invalid character exists it will be not. So in that case how you get that is okay. So you are having alias piping it through that particular function. So it will take the string and it will give that maybe of an int. So finally your end result is like you are having a maybe string but then you are getting maybe of int. The point to note here is both are maybes. That means both are black boxes. Let's say yellow was a string and green is a int then only that yellow changed. It's similar example for the list. I think I'll glance through it or I'll just leave it for a few seconds if you want to read the types. I want to greet only if that person has an alias considered. So depending on a person my greeting, I would have called it greeting would be just the actual string which I want to greet with or it may be not. Correct. So what I am passing to fmap this is a function which takes a string and returns another string. Like it just prefixes hello and gives back the string. Now I want to convert that function to the one which works on maybes. See my function over here, this s over here it's a string and it gives back another string. I want to convert this function to works on maybes because what I have is maybe alias is a maybe string not a string. If alias was a string I could directly use this function I don't need to fmap. So because I simulated the scenario where you will have a function inside a maybe. Because that's why that fmap is over there where you are expecting a value out of a function but if you don't pass all the required parameters then you do partially apply what you get is a function. And going forward we will talk about where you have a entire list of functions, how you sequence through all those things So that's a perfectly valid scenario where in which you end up having functions embedded inside those contexts. And we will talk about state monads. So it doesn't hold a value. So that's why when we look that yellow thing it's a value or an expression or some kind of a computation that we could do and the box is a container treat like a box. So let's go through the, would you like to see some code? Okay, so this is a typical problem we have seen in these conferences before and from interview problems and all those things right. So I have kind of simplified it. And let's look at that and see how do we solve that using three different ways. We will take you through that. So the first one okay, so say a rover analyzes a rectangular platoon. It understands two commands probably move and turn and move is let's say one step, very simple. Turn left or right. And after each command or set of commands if you are sending multiple at the same time it responds back with which position the rover is in. And assume that starting position is always 00 on the top, left or right. And the direction it is facing. And now we need to build a simulator to try this out. And I know the original problem has a bound. Like it knows like the coordinates and then it should, if it goes right to go outside of it we should indicate an error and all those things. For simplicity sake let's say it's infinitely flat and it never ends. Like you can go as much as possible, right? So do you want to see an Java implementation for this? No? Okay, I'll just show. Let me ask another question. You want to see now or at the end? Like after going, after the end? I have this slide in both places. Okay, good. So let's defer it to the end. So look at the basic implementation. So what are the types here? Why do you think the types are like? You know the problem domain now like are they type? Okay. Position somebody said and the command is a type. Command holds something but it's a type. Once you start defining it there are others one will come in. Like for example you need which direction it is facing. The position contains direction but forget that high level, higher level we'll see now. And the functions are probably operate. Like I don't move and turn. I wonder if I have a common word like operate. And the implementation is just this, right? It's like you give a current position you start with 0, 0 and probably some direction facing north south whatever it is. And the command and you get a new position. That's all it is. So it's one function which takes this. Of course you'll have the type definition for other things. Do you think that's what it is? It could be very simple. Let's see. So we'll have to make it a little faster. So this is the first one, right? So there are, alright. Let's look at this now. So the light is kind of not readable. Is it readable at least? Sorry. Frankly I don't know how to change. I'll increase on further. Okay? Okay, cool. So we have some type definitions over here. Command is move. In this case you can move multiple steps but we'll always use one as a value. Turn. And turn has like left or right. Position has CX, Y some direction. Direction is north south east of X. So these are the types. So this kind of your modeling kind of your domain. So this is what it is. I don't have anything for the rover. So the rover doesn't do anything. And I have a move function which actually takes the position, how much to move and use a new position. Turn similarly, there's an implementation for turn blah blah blah. So what is of interest is this operate. So given a position and a command, it gives a new position. So if the command is move in the corresponding distance and call the move function, turn, direction to turn, call the turn function, if it gives there's an undefined over there. If it's something else, you just retain the current position. I don't understand what you're saying. Is this clear? So now the thing is this works for one command. So how do you, you will send something like it's a commands are left or a left turn or L for left turn or for right turn MMM. You could give L MMM, RRR, MMM like 20 different characters. So it's a series of commands. So that's where the work is. So let's look at this. I kind of weirdly named this option one. I should have changed it. But anyway, so you enter the, get the command and then what does this do? Like it converts string to corresponding command and you're actually folding. So you fold. So essentially takes, you have an initial value, fold L. So the initial value becomes your left side argument. You have a two argument function which takes the initial value, takes the first from the left side, applies it, gets the value, updates the value, and then take the next one and keeps on going. So, and you have a result at the end of the day. And then we are recursing it, but when you run it, like it, it will keep on, and this is a console application, so it will keep on asking for what is the command that you did. So in this case, the point to note is there is no rover type as such. It's only position command and other things. And every time you need to keep, you know, you are managing the position. Like every time you call the function, you get your next position. So you need to keep track of it because you need to pass it to the next level and that's what fold does it for you. So you are explicitly using fold to ensure that you are managing the state yourself. So we'll see this. Okay, let's see this. Okay, fine. Yeah, so I'm just calling it. So it will say LMMR. So it's just printing out whatever command. So like turn left, turn left turn, move one, move one, turn right turn. And your final position is like equal to minus 2 whatever it is. So then, so now we'll reverse it so that it goes back to the original one for RMML. It goes back to the original one. So it's keeping that state. It's not always starting from there. Let's say you need to create a map of intermediate positions. Can you do that? Or something that you think about? Like I don't want the last position alone. I want to know the path which trace, like first it went to x became minus 1, then it went to minus 2, then it changed. So I want the position of individual. Let's say you need to plot a graph. So that's something you need to see. So getting back to the slide. So we told that there is no type row over. So now think about the types that you bring in. So you are operating a row over. So probably you need a type called row over with position as a type parameter. Do you think that makes sense? So your position is the only state for now. So you are holding a position. You need a container that position. So the types would be like let's say row over M, calling it as row over position and position command. The function is run over. So that's what it is. Nothing much. Only thing is earlier we were using only position. So now we have a row over which contains a position. So that's the current row over and you get the new row over. And it could have other static non changing aspects of the row over. We can show that in row over here. So that doesn't change. Only the position changes. We want to see this. So we will go to the next one. I will show you this but there is a reason. So this is what it is. So now I want to see how do I avoid? How can I not do fold? And how do I avoid managing the intermediate positions? I know the fold does it for us but I want to avoid that. I was exploring the solution and I thought I will make row over M. I was learning monads. I thought I will make row over M. So this is that attempt. So I will just glance through it. If it is to be monad you need to make instance of various type classes like functor, applicative and monad and all those functions are defined. But the point which I wanted to convey is when I did that then finally made it work. What happened is we will just go through this. So same as last time you get a commands to run and you had to create this intermediate stuff called position function. So what this is you see the run drawer position, command and position. So when I map it over this command to run this becomes a list of this one exactly position to position. So all I had in that list was not list of row over M's. It was a list of functions and function was given a current position given new position. I do not have a command in there because the command will be different for each command is different. So you cannot have a standard one. For every, you partially applied a command you get a function given a position another position. So this position function, so I am not using that row over M at all. I mean it is okay. It is like given a current row over give me a new row over or given a current position give me a new position. So this led to something new. That means probably in these scenarios where you have to travel the state it is not that I do not hold that yellow thing is not position. Probably it should be a function. That is what is coming out over here. Like ultimately you are translating that to a list of functions and then working on it. So probably originally what if it had function. So that is I know that I just hold bypass that code walkthrough and demo but the core part was about this. That position function, pass functions was a list of position to position. So this gave a clue that this was those three lines of code. Like run over is position command position command to run and when we do this you get a over position to position. So what it means is this one is a function. It is no longer 10 minutes. It is no longer a value as such it is a function and that is state of course it is actually incorrect. It is not a specific definition for that function but in general it is a function. So it is a context which holds a function. Now what exactly that function is? It is of this format where you have a state and you pass in a state and then you get a tuple of the result of that particular computation and a state and then new state. If I map it to the current one, current problem it is like change it to over s. So I have a I will give a rover with a position. It will give me for that computation what is the position and it will give me an updated rover with position as one of the state and other state probably remaining as it is. And it has got all those functions over there what we talked about like fmap, ap, this thing. So since you are in C for the completion state there are these are the tools that are available. Like once you have this function you can use these functions on the monad to either to get a final to get hold of contained value like run state gives you back that function whatever you have but you can invoke it and get the value. And exact state will give you a function which gives only the final state. You do not care about the result and if value is you do not care about the state you get to handle it. This is for the completion state. This is fun and so let us go through the again and you have it here. So this is over s. Okay so which is so where is our so we look at run rover right. Run rover takes a command and the rover and gives back a position and another rover right. So look at this part rover s gives the position rover s. This is exactly matching your syntax of state s arrow a and s. So this is what probably we need to wrap it inside a state monad. So you have that rover data state rover s and position because this is the state and this is the value. So rover s gives back position and rover s. So this is your rover data is your state type that goes to state monad. And this rover s itself is like okay I know that it is a position that is the only one at this point it exists. Now if you go to the implementation of it the same thing you get a new line you get the command and here you see fmap to rover command run. So what this does is I have a command and I am giving it to rover. So it gives me the state monad state is a like a constructor function kind of thing where you pass the your wrap model. So run rover command will give you this over to position rover s path to state you get a state monad. So you get a rover data. So this will give you list of commands to list of rover data. And you are sequencing over that. So you can see implementation in state monads. So what sequence does is you have list of monads, list of rover data sequence will give you rover data which contains list of your positions or list of the result types. Or rather it contains a function if you which on which if you call x6 state or run state or eval state you will get that value. So that is exactly what you are doing here and finally you are doing a run state. So run state gives you a function s equals s arrow aas. So you are passing that rover function and probably initial rover, initial rover with an initial position. And this gives the tuple position and rovers. And with the sequence magic you know what this position is? These are all the intermediate position that it went through. I will show you that. And this is your final state. So you are printing the intermediate position and the final one. So this is in fact it is not it is just again syntactical stuff like sequence implementation if you go it internally use of it. So it is just that at your level you do not you think it is magic like you do not write it. So we will show this demo another 4 minutes. I need to change this. So this is rover using the state. All right. We will see. Okay we will give the same command LMMR, cool. So now we have at least we have the same result as last time and this time it has printed the intermediate position. So the default position is 00 north. So first it said turn left so it became west 00 west then it moved one step so it exists minus one then moved another step exists minus two then again took right yeah right pointing back to north so that is what is minus it is not. And it gave the final position over here. So now let us reverse it RLMML. So this again initial was minus okay after turning left it became east then minus one then zero then towards then again left turn it became north. So it kind of came back to original position. So essentially it is here. So the key point is the container the box or the mona whatever that entity holds a specific function which takes the state and gives a value in another state. So you can sequence such objects which will actually run through the entire computation given an initial state it will give you will get all intermediate results and the final state that you need. So that is pretty much what I wanted to show. Any questions? I want to see the Java I am sorry that is cool. You just have to change the display property. But eclipse changing the font between the values when it is coming up any questions? Yeah any questions until then? Okay currently my hassling is learning and hobby. I did over for like Kala for I think I started doing Kala like four or five years back. We don't get to use our skill at job. But it's until I'm still struggling to break out of that initial shell and to see whether do we really when we solve a real-world problem do we need to implement these monads ourselves like some containers ourselves that's what I thought like for Rover I'll do myself I'll be represented as a monad but there again okay there's something on state monad so you can use that and that helps actually. So I haven't still reached the problem in next year. So okay so this implementation has like four classes four plus eight classes it's probably a bunch of stuff it's there in jitam I have the link and I wrote this probably 2009 or 10 at that time these are the best solution that I could write. You are not actually making the monad kind of thing right? This pure oh I mean so this actually did it in 2009 and that time I thought is the best solution anybody can give this best and compact. Even if a senior person is recommending it then you can sort of do a small POC project you would still not be allowed to use Haskell at work. See it all depends on where you are you're running a let's say you have five employees in your company and you have to do that as a group yes you can but if you are in a 350 member team and training I mean to me I still feel bring folks on board and start writing production code in Haskell it's extremely difficult and you probably you probably need a different kind of people than team in order to do that in a larger scale. So but you can still attempt smaller stuff and to me I have talked tomorrow but I have experienced this you apply this basic like don't worry about monads and apply this basic principles probably about no mutable state and about writing as much as I make writing pure functions and then keep all your impurity and that kind of stuff probably around 10% of your implementation that itself will give you a tremendous difference in how you build things and that probably I'll be talking about tomorrow. I think Michael had a talk on what you're facing and how to break through at your work. We can I think Michael has some great insights on that especially around how to build your community in larger enterprises and how to change the conversation from productivity in lines of code to actually maintainability which is the language that your management would understand. You tell them in the school we use monads they'll show you the door and they'll get out of here. Yeah so not only applicable but at least my experience is that folks are very receptive and now a lot of mainstream Java has all this probably doesn't have monads but like all the basic constructs that's good enough to make a huge difference but the pitfall there is you can still write Java code so that's the pitfall and that requires developer discipline that's a bunch of issues around that but yeah that's true in fact the problem there are numerous ways to do one thing and that's always a problem. Things are simple if you have one way to do certain things. I'm going to ask you about that tomorrow's talk especially how it relates to Scala numerous ways of doing the same thing in Scala. In Scala also you can write Java code. Thank you so much this is a great talk. Thank you.