 So, yeah, let's talk about pattern factors. I'm Alejandro, but we have very few time because that's like a lot of slides and a lot of things, and I would rather prefer to use the time if you have some question at the middle, just write your hand and we can try to figure it out. So, first, what's the idea of the talk? So, we're functional programmers, so functions are first class. We can do all sort of stuff with them. We can use them as argument. We can return these values. We can combine functions to get new ones. So, we have this combinator with really combined functions to give you new functions. We can speak about functions even given a name, which is like one of the weirdest thing I found when I was learning functional programming. Like, why would I create a function without the name? That didn't kind of make sense at the beginning, but at the end it does. So, the question is, can we have first class data types? So, can we go even farther? Make everything first class because we think that everybody should have the same right. So, data types should be there too. And the thing is, we have some parts of this. So, what do we have? We have parametric polymorphism, which is a fancy way to say that types can depend on other types. So, we have this list with our list of some type and then we give an argument to say what is this type. In Haskell, which, by the way, will be the language I will use throughout the talk, we have type families, which are sort of functions at the type level. So, we can really have this element which, given a type, give us the type of contained elements and this is like sort of a function. But we are missing many, many things, so we cannot combine, we cannot easily have a language to combine data types to get new one. We cannot express something like what's the shape of a data type without giving a name. We are always forced to say this is the type list. We cannot say this is a type which has like things and then recursively the same kind of stuff. So, we don't have a language directly to do this and this talk is about how we can do this. So, first of all, this is part zero of the talk. We have to set up some things and at this point I would recommend you that you just faithfully believe me what I'm saying. So, this will work out at the end but now it will completely make no sense. Why the hell am I doing this? So, the first thing is what we are doing, we can do it with functions. So, we have this normal factorial function which is recursive and we are going to think, okay, I don't like recursion at all, it's wrong. So, I want to have all my recursion only going through one function that I trust, I don't like it but I trust it which is fixed. And we can do this, we can separate from the factorial function and a skeleton which has no recursion and then tie the recursion so make the loop using this fix. So if you haven't ever seen this, that's the place where you need faith, this actually works even though you have something like let x equal fx in x and everything being called x is important for this to work but the main point is in factorial we are replacing the recursion with actually an actual argument which will represent the recursive calls. So this when we are calling f here at the end when we use fix this will be tied to be the same factorial function so at the end it will work out. So now that we can do this with functions we can look at data types and data types have some of the same thing. We have recursive data types like this arithmetic expressions and you have some base cases and you have some point where you make recursion in this case you have literals and you have plus or times other expressions and at that point you also make the recursion and we can do exactly the same thing. We can break it up into things. We have some kind of data type that I'm going to call pattern factor just because it's a bunch of cool words together and we are replacing this recursion by an extra argument r so whereas before we call arith x all the time here we are using r and then we have one data type one single data type that we have to believe that will tie the recursion which is this fixed data type which look a bit weird but this will actually work so this fix is going to tie the recursion at the data type level. The difference is that before we just write our so imagine we have we want to do something like plus then we have plus one and here times two and three and if we want to write this sort of thing using the white data type we just write this so we have right plus literal one you know it it's it's easy but if we want to use the other part we have to include one extra constructor each time which is this in data type so every time we want to have something what we have we want to we have to say oh please I want to do a step a recursive step so I will call in and then use one of these things and by the way we are tying the recursion we can ask for a new step to go with another in so basically your code ends up looking something like the orange part we have exactly the same structure but we have this in extra things so this thing may look like okay we I'm already telling you to write more code which is bad I've heard but if you're using new version of GHC you can actually hide all of this with pattern synonyms which are sort of a way to say whenever you see times I want you to read this even if you are doing pattern matching so it's not like just creating a function it's also creating a way to look at things so some people might be wondering okay functures are a nice word but you shouldn't be using this without even proving me that this thing is a functor so these are called pattern factor because actually when you make use this techniques every time what you get with this extra R argument it's a functor so you can always write a definition for this and this is always look the same you just make your recursion with F map on each of the of the parameters of the of the R type so this construction would always be a fun to it's not important that this is always well would be important later on but this is always deals a functor actually this is so simple kind of functor that you can also derive it yourself so you don't have to write this code so so okay now I assume that you are going to have believed me that you can do this with data types so do you split this recursion from the patterns so have we gained something so at this point we have already gained something so imagine that I want to have this kind of trees but I want to add some information at each point at each node so I just want to add a translation into Spanish because somebody is going to read this so I want to add here like a string and here as it's in Spanish yes so I want to add this thing so if you think about it this is not actually changing the structure of my pattern is it at each point I want to introduce a tag so this is changing it is not change the structure of the data type is changing the way I am doing the recursion I want to do recursion in which at each point I want to attach an extra tag so I can do this if we have a pattern factor instead of a recursive data type I just change my fixed point so I just change my my purple part and my patterns are still the same so I can reuse the same data types over different kind of trees structures of course now when I create a value I have to attach all the all the extra tags but I can do this and the pattern factor does not change so we have already want something but we can also use this technique to have more generic functions so what we are going to try to do now is to to create some kind of generic fold function so if you look at fold functions you have fold are like this or you have fold a which is a fold over my arithmetic expressions and and if you write this thing so this is this thing which traverse the tree and sort of put together the information and at the end when it just becomes one piece of data so you will notice and this is shown on on orange green that there there is always the same skeleton so you have these types which are always like my pattern factor so you see integer r r r r so that's exactly my pattern the shape of my pattern factor and then they return this value r and if you look at the list so how how is the pattern of list it's either a and a recursion or just nil which has no nothing so yeah like my the second orange part in folder is just invisible because there is nothing and you notice that every time I always called this same function in the recursive position so there is some kind of structure hidden here and actually we can write it easily so the same the same fold that was so long to write for every data type we can write it once and for all for every data type and with a purple thing so it's just one liner but this is more generic because now instead of just any kind what one specific data type we have any data type which is represented by this P so this P is our our pattern factor so if you take this and instantiate to a list you will get your folder if you instantiate it to arithmetic expressions you will get your fault a by the way this is called these things which go from P of r to r are called algebra so this really doesn't matter but if you heard about algebra some programming and bananas lenses and all this kind of things this is all about this kind of stuff so we just wrote the same thing it went just one line and and you see that there is a recursive call so we are calling g fault inside and and why we need why we need it at the beginning things to be a funcers is because when we are doing this we are applying things in this two position which are the position in which we are funcers over and in the other place we do the same thing so we need some way to do this mapping and we do this with F map so this is why we need things to be pattern factors so if we want to do something like please give me the what is the result of this expression we can do this by using g fault for arithmetic expressions instead of writing the the all the skeleton we only have to go to the to the essentials part what you do for each constructor if you have a literal you have n if you have plus and x and y are going to be the results of the computation that's go upwards you just going to add them up or if you have time you are going to multiply them so so we have here two things that we can already do with pattern factor we have we have we can change the fixed point and then attach new things or we can create generic faults so now I I hope I've already convinced you that this technique is going to go get us somewhere so now we're going to see three bigger things where we can use this this idea of pattern factors and the first one is is coming from from the question how do I put constructors together so I imagine I have I have this plus and times but somehow I want to add some new operation like exponentiation so I can define a pattern factor for exponentiation but how can I push them together put them together so you have one data type which is like all constructors together and this technique is called that the types a la carte so as I said our aim as extensibility so we have the pattern the pattern factor above which where I'm splitting the literal from the operations and we would like to have some kind of plus call it combined plus whatever some kind of of of combinator which put constructors together so our arithmetic expressions are going to be just like the fixed point of these two things put together so imagine plus is just putting things together and if we then want to add minus and division then we just put it together with a new plus so this is getting as extensible data types at each point we can decide oh wait a minute and for this thing I need one extra constructors so I'll put it inside and then I will combine with plus so can we define plus how should plus look so if you think about it if you have two functions basically what I have to tell you what you have to tell me at each point is which of them are you using so you can use either literals or plus and and times so just tell me oh I'm using literal oh then you're allowed to use literal I'm using plus so you're allowed to use plus and you can do this with this green definition so this combination of these two patterns factor F and G is either please go to the left so choose the pattern on the left so then you give me an F and and or you go to the right and then you give me a G so that's everything you really need to know which one you chose at each point and and and the nice thing of this is that this construction still returns the function the functorality so if you have two functors the combination is a still a functor and and this is sort of a strange looking code if you are not used to this thing because the F map on each F mat has a different type so so it's looks like I could write the same stuff for the first and the second things but I cannot because really the types involved are different but this tells us that if we have two functors and we compose it with plus we have a new pattern factor so we can still compose it with another plus or we can do our fixed point or we can do our fault or we can do our tagging so we are still in the same kind of thinking the problem now is that our values require at each point to tell whether you want to go left or right so what what before was a bit annoying to have all these inns then now you have to have the inns and the go R or go L so this is quite quite annoying if you want to use it all the time especially because if you if you are combining a new functor now you have to say go left go left or go left go right and you know it's scale if you have like four then you will have to do several combinations so this is a bit tricky there is a solution for this which I'm just going to tell you that it exists so there you can define functions that inject a data type F into anything that has F inside so you sort of it seems reasonable that if I have literals if I have something that is built only with literals then I can make it into something which has literal and any more any more stuff around so you can define these functions and this is the how you solve this problem because if we had something before which only have something you just call injection and you make it in a speaker as you want so the detail there are many details to construct this so you can read them in in any in any this to two articles but so I they're they're nice to read but we don't have the time today now we don't have the time so okay we have extensible data types that's cool but if you have extensible data types you would like to have extensible functions because you would like to say oh I have a function like evaluate and then I have my literals and I know how to evaluate my literals and then I have my arithmetic operation and I know how to evaluate them and somehow since our our so you could write these functions but it will be tied to one a specific functor we don't know yet how to have like a part specifically for one functor and then for the other factor and then how to combine these functions together so so the question is we got extensible data types can we write functions that are extensible over these data types and this is extremely easy well extremely easy depends on of course on our definition what you find easy but this is all the code you need to write ebal so basically the idea is that now our function is going to be defined as a type class but this type class is the type class or fun of functors that know how to evaluate themselves which are evaluable somehow so each of these have to give me a definition for the function about a ball underscore so act actually what we need to what they need to give me is another algebra oh it's interesting I find it interesting at least and so you see that that now we can write a definition of a ball for the literals and operations and these are yeah yeah so basically what what we are left is we know how to tell or how to evaluate literals how to evaluate operations but we need some extra boilerplate code which is how do we evaluate a composition of functors and this is always looks strikingly similar there's always something like this if you think about you either go to the left or to the right and then you say if I go to the left please call the valuation on the type of the left but this is taking care of the type class system so this a ball will call the thing which is on the left will call the ball on F or if you go to the right please call a ball on the right so and and the last thing you need to do is okay we have about a ball for P of integer but what we really want to have is so for for P but what we really have is something that is the fixed point of P so it's gonna be fixed of P so you need to unwrap this fur sorry it shouldn't be fixed it's right in there sorry so you have to unwrap this in operation that we had before and you just do it by calling a ball and then recursively calling a ball on the subtree so you are tying the recursion again at this point so so this is how you can write a sensible function you just have to think beforehand that your data type is gonna be extensible so you write it's a pattern factor and then you can combine them and get extensible functions and actually these functions are really extensible so if you now add exponentiation you add the factor you add the the instance for evaluation and then you don't have to change anything you don't have to change the instance for combination you don't have to change a ball so a ball is still the same stuff so I think this is pretty cool and and yeah I think this is a small digression but I think it's interesting to do to know where these techniques come from and this is come from from trying to solve what is called the expression problem of programming languages so we have object oriented programming we have functional programming and and somehow they have different trade-offs so if you have if you have object oriented programming it's very easy to sort of a new constructor to a data type you just subclass it and then you have animals and you add a dog and a cat and then you can do this with modifying the animal the problem is if you want to have some some new function which is which works across all animals then you have to change the animal class so you can subclass it in all the rest so you sort of have it's easy to subclass to add new constructor but it's very complicated to add new functions and so you need to modify what you had at the beginning and there are these extension methods which allow you to do some of this stuff and an fp it's completely the opposite it's very easy to add a new function you just add it whatever you need it you don't need to to tell any data type that you want to a new function operating on it but if you want to add a new constructor to a data type this becomes impossible you have to modify the search code and this is bad because we we need to go to whatever wrote the search code and and see that everything compiles again so this that the type salad card is is something that the fp community came to solve this problem on the unfunctional rule on functional languages okay so that's one one thing we can do with pattern factor so let's go to something new which is to build free thing is especially a free monad so I'm not trying to tell you what a free thing is there is a talk after this which will tell you much better than I do but I need you to to get at least the intuitive feeling of what a free thing is what do we say when we have a free monad a free monad free whatever so so the idea is we have a class we have a class X and we want to say what a free X is so a free X is gonna be just a parametric data type so a data type free X would take a type A so and then we want to be able to define an instance every time for this free X so we want to make free X an instant of X with the less amount of conditions so so we want our conditions to be nothing or the smaller they can and if conditions is some other kind of concept then we speak about the free X over a Y so let me make an example so we speak about the free monoid over a type and why why list is a free monoid over a type is because for every list of a we can define an instance of monoid and we don't have any condition so our condition is just to be a type so we can we can define it this way so it's important I'm speaking about a free monad not the free monad which is a much more stronger thing to say about something so I'm not claiming that this is the free monoid and you can you have long rounds on the Haskell cafe mainly is about what's exactly the free monoid in Haskell which is not actually the least but okay the point is we want to define free monads so what should a free monad look like there's it should be a data type free monad which takes an F and given some conditions for F that we want to we want to figure out we want to write return and bind for this for this data type so so our first guess would be you are speaking me about this fixed thing let's try with fix so it fix takes an F and we have this fault operation which sort of resembles the bind operation with sort of resembles might be depends on on what did you think about it so but you have some problems first of all a monad is an extra type so you need to have fix of f of a so because now you cannot define return so how will you return any a into fix of f fix of f only have values of the fun of the functor f and and also another problem is that g-fold does not change its type but this is also the same the same problem there is no extra type variables to change so it doesn't change its type so so we can think about okay what we need we need some extra thing that saves value of type a so let's include it so let's use our idea of an extensible data type to add a whole of type a so now your free monad is not only going to be things of the pattern factor f is gonna be things of the pattern factor f of an a which is like in its own world so it's it's a whole there so you can see that the type whole is also a pattern factor but is completely disregarding whatever the the x is so it's always be a constant type a so if you add it to it then you can write a free monad definition so we have any factor we added a whole and we know how to add a whole because we know how to add data types now and by combining this we get a free monad and fortunately you this is not valid Haskell and why it's not valid Haskell is because when you have a type defined like this you cannot partially apply this so it's it's not legal to write free monad of f we only have to we always have to write free monad of f of a it it really requires us to use the synonym fully not not just a part of it so if you if you look to the to the definition of a free monad over a factor which by the way is the condition we figure out we only need factor f if you look at the definition you will find something like this which is just expanding what we had so it's either return which is the this whole or it's either a recursive which is a fix over this free monad so this is just expanding this thing to please the Haskell compiler and we can write the same the same stuff here so we have a factor and you have a free monad over f so what's the deal with free monad why everybody loves free monad this I haven't told you about that I just thought oh these people want to know what free monad regardless of its utility but there is an utility on this so yeah yeah I even like to think that free things are a design pattern of the Haskell language so so if you have something like operation so in this case you have a key value store you can represent the operation that some this a store can perform as a free monad over a specific factor and this factor is the thing that that represents the operations so if you have some kind of system you have the basic operations and you usually have all kind of skeleton to combines operation so you can sequence them you can perform them in parallel and this is given by this free monad the structure so at what what can this key value store do it can either get a value so you give it a key and then it gives you a value you can use to apply to a function so that's the V to R or you can just put a key with a value in the store so if you now define the free monad but you get it sort of a way to define programs that use this key value store and and this is an example of it so this is put in three and then get in three and with the result of three it will just it will just return whatever it got so this is this is how you can use a a functor to define a free monad and this represents sequential operations over this kind of basic primitives in your in your language usually you don't want to write this example in this way you would like to write this but you can do a sort of mechanical transformation by just calling return at the end of everything so it's it's not very complicated to do this and you can you can always do this to get a more monadic interface so what what you got from this so this thing only represents operation but it doesn't perform any operation so example isn't actually looking into any database it's just telling you it's just describing a program which does something a database so that means that you can interpret your description in different ways so you can do it in a real machine so you can say oh I have like a key value store connection and I will every time I have a get I will actually get it from the from the key value store or if I have a put I will put it on the key value store but you could also find another interpretation that mocks the operation and this is great for testing so I will define something we just recalls these things on a list so if I have to test my system I can just create sort of a unit test run it through mock kv and figure out whether the result is what I was expecting without actually having to run anything on a database and I think this is an important lesson to be learned at this I think that's one of the things that has those empowers me to do that you can separate completely representing programs from interpreting programs and and usually the good thing is that representations of a program since to be instances of general concept like function like monad they always have this kind of same structures and interpretations or even interpretation are always kind of fault so you can you could have defined this as generic faults but the nice thing is you can have several of this interpretation you don't have to boil anything down into the system and well as you as you may know Haskell doesn't only give you free moment it gives you a lot of other things for free so you can look at the free package by Edward Comet and you have free moments free moments free free whatever you can kind of do this kind of stuff I think that the free moment is the most useful one because of this thing which you can interpret but you can but but you can have more of this construction and figure out how this should be and this is I think this is a nice and nice thing to do so so okay this is of course awesome so why the hell doesn't my compiler allow me to do this from the beginning why can I use my data types as first-class data types I would like to do this now I need to do this so and if you think about that that's very clear because what what what you do when you do the writhing show is you want to write a show instance but you could have written this if you know what is the pattern factor you only know need to know what's the pattern factor the red is always the same just parenthesis and angry cars so why don't you do this so actually we can do this and I will show you how so let me check the time oh I can even tell you this slowly so so we we know how to express choice so we have this plus operation that allow us to say oh I want to have this comes this factor or this other function so we can sort of say I want to literal a plus or a times but we don't know how to describe its constructors so we don't have a generic way to say oh this is an integer and this has an R and an R and an R so what we are what we are looking forward is to have something like this so we have this plus which is like an or represent a choice of constructor and then inside every part we want to define what is the structure of the constructors so for this we need some some things so we need first of all some way to say oh this recursion so we can think oh there is some kind of recursive pattern factor which represent this I will show you later how we can define this just try again have a bit of faith that this will work out we have this we have this whole we had before the whole which represent a constant thing we can represent this thing that oh here is an integer oh here is a whole for an integer and what we need also is to put something together so we need to have sort of a tappling but we need this to be extensible so we have to have some kind of and operation so what we had before that our arithmetic expressions they are now this is going to be represented this way so you either have an integer or two recursive position or two recursive positions and we we forget completely about the names of the of the constructor they are not important in this case because we can always know what we have chosen by means of knowing if we've gone left right in this case or left left so so okay this combination actually exists and they have this nice property that you can you get you give it two functions and you get a new function so we know about holes we know about choice we have a product of functions which is just two things together so you have F and G applied over a because this needs to be a factor then it's f of a or G of a there it is we have we can always express we can express recursion but if we remember we express recursion later on the fixed point by this our operation so we only actually need to to have the same operation here so this are is really like an identity you do nothing to the to the parameter and and then well if we are going to do this to the end then we also need some extra thing for a constructor we have no information so how would you represent a list with only this without this well you cannot do this because you cannot express something like nil you cannot say oh this has no information attached because you always have to choose some of these functions so we need to express an extra one which is unit which is like nothing no information attached here so we just forget about our a completely and doing this we have anonymous data types so we have data types in which we don't give it a name we only give it a structure a shape so our list can be represented as either unit so that's the nil case or a cons which is a whole of type a and then recursion and then our list are going to be fix of this thing and if you want to go all the way down you can define nil and cons as just synonyms of this thing so when you have nil is just you go to the left so you go to the first case and well you have nothing to say you have only have unit or if you want to have a cons you have to go to the right so you have the second one and then you either you have to give it a whole and then the recursive thing the fixed one will take care of this working in the way it should so you can do this also for arithmetic expressions so you can define it as either a whole integer or two recursive position for plus or two recursive position for rec and you just can do the same thing with patterns synonyms to have the same name you had before so the nice thing is that ghc already gives you this so it just only give it shorter names which I think are not shorter just because you want to write less is because you want to look more clever because of course if you know what kcp is you are strictly more clever than if you know what hole is which acts a hole so that's that's the names that gives so instead of well the Sam and approach are the same and instead of go left and go right they call it L1 and R1 and there is a reason why they are called L1 and R1 and L and R directly but yeah that that's just make it another day so so we have you need to have products so now we have we actually have all the building blocks to have first-class data types on our compiler so the only thing that is missing is that if you write Haskell code you usually write normal data types so you wouldn't write list in doing a pattern factor and then taking the fixed point and writing the pattern synonyms so you want to use normal Haskell code apart from the fact that it's completely irrelevant that it will using this will be like ten times lower but yeah so what they did in ghc is okay it's telling you okay if you want to work with your normal data types do it and if you want to use this generic representations please give me a way to convert from your data type to a generic representation so this is the generic type class which is like the whole idea we've been working on on the compiler so you have to give me if a is generic if a can be described with all this fancy pattern factor you have to give me what is the representation so if you haven't seen this this type in a class forces you to to to give a definition of a type when you implement this class so it's sort of a method well not a method it's a method which is a type it's like a function which should return a type and this is a colon associated type family and then you have to give ways to convert from a to the generic representation and the other way around so this is this is how you want to do this so if you think about it if you want to give the instance for list so we already have seen what is the instance for list so we have to give an unit and then a whole and a recursive position so this is how this is done so there is just one a small detail generics don't use this fix operations that when you have a recursive position you just say oh this is like a constant of the recursive type so you have here k1 of type list of a this is a small difference and why you do this is a small difference style so I think that the other one is a clearer style but this one it's a bit more performant so you want to lose some of your performance but maybe not all of them all of it so and then if you have to give tell me how you move from nil and cons to the generic representation and the other way around so okay you want to use this technique but seriously are you gonna write this code so are you going to get a scrap piece of paper figure out what is my pattern factor let's write everything and imagine you have like I don't know imagine you have something with more than two things which actually will mean that this will like three lines that's terrible so yeah just ask the compiler to do it for you because this is automated so you can add the right generic at the top of your source file in Haskell and say oh please derive generic for me so yeah if I want to give you all this thing for my arithmetic expressions I will just write this and it will generate all the code for this so so we are good we don't have to work too much we only have to add well one line per thing because the the other one you only have to one per source file so this is amortized about all your so if you put all your data types in just one big file this is like completely negligible cost so so then we can use the same techniques this data types a la carte approach to define data type generic equality so you have this deriving EQ which does it for you but you could have written it directly by using this data type generic kind of stuff so this is exactly the same thing so you have to give a type class and then for each of the possibilities which now are not they are not any kind of pattern factor there our basic pattern factor you want k1 plus and times you say what you want to do and and if you think about and this is how you would actually think about a structural comparison so this is telling you okay if I have two tuples they are equal if they are equal in both their components if you have a choice of constructor these are equal if they choose the same constructor and then their information inside are equal which is exactly what you are saying there so if you have L1 and L1 then you continue looking but if you if they are different then you already know that they are not equal and you can give false as an answer so this is how you implement equality usually how you think about it and then the only thing that is missing is a wrapper because if you want to use equality you would you don't want people to know that you are doing all these generic combinations so you want a wrapper which goes from here and of course you need to to have generic here but people have to write the right generic I think it's a fair amount of code they have to write to be able to use this the problem is okay you can implement equality but you cannot implement show what that's what I said I would let you know how to do it and the problem is that we know how to choose a constructor but we lost the information about the name of the constructor so what is the name is it a field how should we need all this information to be able to derive a show instance so what what GC does is add a new constructor M1 M1 from metadata with just does nothing so it doesn't record any information on the on the value level so you have nothing else to do only an M1 extra in your in your data type but but this I and see by the way this is called this is ICFP which is the name of the International Conference of Functional Programming and I think this was a pun from the writer of this thing but but anyway this is information about your data type so if you go to a GHCI you can actually do this if you have I think from version 7.8 or something like this and you and you say well kind of rep which means that please give me the type which results of this type family from this type function rep applied on wool you give me the kind and this and this exclamation mark tells you please also give me the type not only the kind of the type you will get something like this and you see that this what you would expect is to constructor which has no information which are true and false and you can choose about it but there is some metadata which recalls the name so if you ask data type name from true so you need to give it a value but you have true you then you get bull so it recalls what the data type name and if you ask for constructor name it will also tell you the constructor so with this you can and you have more information so what's the model it was defined it is a defined as a record all this information with this you can you can implement a lot a lot of stuff you can implement equality function traversable all of this in a generic way you can do serialization to JSON you can do to binary so you just add derived generic and then you can use all this stuff for free you can do use deep evaluation you can you can use a very nice package I wrote which sort of extends regular expressions into regular expression which speak about any kind of data type so you can sort of say oh please does this match the shape of having a plus and then all this kind of stuff you can even have generic deep function that work over any data type you can have generic rewriting generic transformation from one data type to other all of this generically but there is just one piece of worrying so there are many libraries for for generic programming in Haskell so this kind of things so I usually like GC generics because it has been one of the the newest one so there has been several iteration of this idea and then they thought oh this is good enough to go into our compiler but there are many others there is regular and multi-reg and then you have scrap your boilerplate which is like a different completely approach based on the folds the newest what the new key of the block is generic SOP for some of products and these have all the same ideas reformulated in a slightly different way so if you are going to use this this is a piece of worrying there are many choices to be done and it's completely non-clear for anybody what you should be using yes and I only spoke of this for data type which has like one recursion so if you want to define like mutually recursion yeah so I was saying so this work but I've shown you only works for simple data type so Haskell 98 data type which only have like single recursion no mutual recursion like these data types needs a type of this and this this one no gadds so you can do this if you if you don't have a headache about the after this talk and you want to know just feel free to ask me it's not a difficult so in summary what we see is that we can make our data type first-class object so there is no more discrimination in our language everything is super first-class and we do this by looking at a data type as a partner factor plus a fixed point and then this gives us extensibility of both data types and function using this approach that is called the types hello car which is just having this type class and then having instances for all of this and this is embodied by the gc compiler and you can derive these things we have also seen some free monads which just use this constructor by adding some extra structure but if after all of this which is a nice technique the takeaway I would like you to have is that the free monad thing is really really really useful in like real-world things because you can represent your operation and interpret and this is completely separate so it's very nice from a modularity point of view so yeah I also have homework because you know I work in the university so I'm I'm I sort of mislead by this kind of of talks thing so you can you can read this these papers they are they are nice and easy to read you can wander around the free package which shows all of this construction and it's nice documented you can browse you can basically read a lot of information about this and this has a lot of documentation about how you apply this and yeah and and if you are writing Haskell code uses techniques to write less code that at the same time is more extensible code so complete game so thanks