This image be our episode 2733 entitled, Writing Web Game in Haskell, News and Notification. It is posted by Tuku Toroto, and in about 47 minutes long, and Karima Klienflag. The summary is. Tuku Toroto is about the game they're writing in Haskell, and convoluted news system they made. This episode of HBR is brought to you by an honest host.com. Get 15% discount on all shared hosting with the offer code HBR-15, that's HBR-15. Get your web hosting that's honest and fair at an honesthost.com. Hello, I'm Tuku Toroto, Tuku Toroto for a short and you'll listen to HBR-15. This episode is upon a game in Haskell, this time I will be focusing on news and notification. This part actually took quite a lot of jobs saving and it's interesting to be pretty complex. I, even while writing show notes, I spotted at least one corner where I could be simplified. So I did go and simplified that before recording that episode. I'm not entirely happy how complex this thing turned out to be in the end, but I also couldn't find anything. And I'm mostly concentrating on the server side implementation, because client side isn't that interesting in my opinion. So what are the news and the notifications? In this case there are messages that the players will receive and something not really has happened in their game. It might be that the planet has been discovered of course fraction of a construction project has been finished. It has encountered the new civilization or something like that, something not for the players. And it's also possible for players to write public messages to the all members of the action. For example, if they want to communicate that there's some good location where everybody should be, or most mostly heading to mine, mine minerals for example, or if they want to coordinate there are some other facts and write accents. I could have implemented the whole thing, but it's just sending that and word a message as a strings and that would have made that things a lot easier. And lots of people who have done with this ages ago, but I wanted a system where entities are hyperlinked. So if you are viewing our news above the discovery of a new planet, there will be a hyperlink in the message to want that you can click to actually take you to that planet. And another one that you can click to view the star system where it was found. As the size of the game grows, there are more things going on hyperlinking news to end this day about makes things much easier. For example, if you have a thousand planet and then you get a message that one of those planets has a severe case of clue, clue in for instance, clue, find them here. If much easier, then if you can just click at the news and view the planet and then start dealing with that, find them here, instead of that you have to go to some display and then search for the planet and sort things and then try to find out. So it links where the planets are. Okay, I would have also sent a plane 8D from the server side, but this is in this good half-type client and the server and the data phase to close it together and have not only to avoid that. I'm writing quite a bit of code and definitions on the show notes, so if you have a client, it might be a good idea to pull those up and follow along as I explain what I have been doing here. So, there's a on the server, there's a server client communicates with over the rest of the AI with sending messages to one of the most left JSON and there's are three new resources for the client's feedback on the server side. These are defined in the conflict-slash rules, fire, and the first one is slash up is slash message that handles get and post methods, then there's a slash up is slash message slash has that news ID that handles delete. This is a resource that takes up. Well, this resource is that in the server address slash up is slash message slash number of the message you want to delete and then the third one is slash up is slash icon that handles get. Get message messages again and this one is used to retrieve some icons that the client can use to display those news because now some of the news have a logical icons mainly the ones freedom by the freedom by the users. There's a there's a JSON set of icons that can be used there. I'll be focusing on the first one of these resource is a slash apisless message because that alone has a quota. A lot of things to talk about. Database, this is a distinct defined in the conflict-slash models file. For the news, there's only a single paper news that also has the JSON attribute meaning that you can serialize easily serialize that pattern for them and it has four yield, four fields, content, fraction ID date and dismissed. The content is that the plan takes to fill where you have you be serializing the news, fraction ID is a, which fraction this news concerns about tables when it was posted and dismissed to tell if it has been read or not. This system means that somebody in the facts says that okay, I recognize this news I don't want to see it. Again, it will disappear from all of the methods of fraction. It's suboptimal type I haven't done to write that better system in the video or play a school set about the average business. The reason I'm serializing the news items to news articles into the JSON and stored JSON in the database is that there's a really many kinds of different kinds of news and if I want to have a relation on the database, it's with fields to each and every of those different types of news that would mean that either I would have a one table that has political amount of the of columns and not all of those columns are used for each error news entry or I would have to have multiple tables basically one table per news entry and that would get also pretty complicated. So I tried to choose the least worth of some here and decided that that meant the serializing data into the content of here. So then on the server side because there are many kinds of methods like I said I obviously concentrate in part of the plan about discovering a new planet. Everything else, every other table of news works in the same way. It just used everything used to have a slightly more complicated thing because users can choose what kind of icon to use each item to write but that I think it still works in the same as any other news entry. So all news articles are the same type, you mentioned it to be called news article and this means that when I had a new type of news article, I had a new value constructor for so there's a single location where there's a list of all the positive news items and all these articles have said that every different type of news has one value constructor that takes a single parameter that single parameter is a specific type that contains all the information specific news. So for example our planet found has a parameter planet found news and that planet found news is a record that has a planet name system name this has strings. Then it has system ID, planet ID, this is a key into a foreign key in the database and then it has the new state. That's when this plan was discovered and so let's imagine we have data in the database already. I'm not going to go how to get it in the database not that complex. So given that we have a data that is how to get that stuff into the database into this object. Well firstly load a news object or a news object depending on how many we wonder what kind of square parameter using and then we have to turn that a string that is of that is adjacent into a news article and for that there's a part-new function that has a type of news to maybe news article. It is very news article because it might be that there has been an error and something incor has been written incorrectly in today's database. So it signifies the signals that the passing may or may work as usually in this case of the in the JSON and it's pretty dense it's decode dot to the device string dot n code u df8.newscontent and this is decode of the JSON, the JSON or what we are using it's free thing we have to jump to couple hoops here you cannot simply decode our next you have to have a lazy by string that for lazy by string that has been encoded with the u df8. So a couple acts like that that's for that reason this is pretty thin in a point free style so if you if you have function that has both two steps and you have temporary values and you are not using those values more than one. You are basically just doing step one and the result of that step one is set to step two and result of that step two is set to that as a parameter to the step three and those steps don't take any other parameters you can simplify things and write a code free style this essentially forms a pipeline so and you can read the dot in that in that definition as a method of so pass news equals to decode of to lazy by string of n code u df builder of this content so basically whatever this content produces is set to the n code u df8 builder and what that produces is set to the to lazy by string and whatever that produces is set to the decode and whatever that produces is the result of the pass news there's also a I'm not specifying a parameter to the pass news this is a because the parameter of the pass version is is only used and as a thing as a last the last a last parameter to the news content so we can use a that a reduction is discounts from the lambda calculus the name of origin isn't important but all is important is that you can avoid that parameter known it to write that write that up there long you you go find this holding out as a long form when it will be that pass news is equals to let content equals to new content is u df8 and code that equals to n code u df8 builder content content the result of the previous step and pi string equals to lazy pi string u df8 and code that in decode pi string so which version the use is in my opinion it's the matter of style and preference one has to remember that the value in in this case the point free style leads to free the readable code it you can get into the really messy looping and hard to read code if you are over using that especially if you are over using that with the code where the point free style does not come from come naturally but you have to do some tricks to be working so now we know how to pass or when we have news how to get that into the news article similar there's a two other functions that little entities entity is something to disturb into the database that has a this basically a tuple of a key and the value so basically it's key of the row and the row in a database and the values of the row turn into object and list of another another third function is for dealing with the list of entities I'm not going to code through the implementation there pretty small I'm sure you can I'm sure that anyone could figure out how to write those given it's pretty good plan so one note how the pass news entities function filters out all the news that it didn't manage to turn into news article so if there's a if you're loading up list of news from the database and then you are passing the JSON data and turning them into the news articles all the all the all those ones that couldn't be passed are discarded so the pass new parts news entities function therefore has a type of list entity news to list of tuple containing key news and this article so we end up with a list of tuples the first item is the primary key of the row and the second item is the news article the one that has been passed from the JSON and turn into object okay I thought that in the passing news there was decode function we are calling decode function that is something that comes with the JSON and that requires that whatever we are passing if it's capable of working with the JSON it has to it has to have an instance of a from JSON type class so meaning that if you have a some JSON and an instance of from JSON type class you can try to pass data into the into that object and conversely there's a two JSON type class that is that deal with turning up object into a JSON and instead of writing this by hand in this case I relied on the and let us go to generate it for us because then I can just write dollar parenthesis derived JSON space default options space two high-pens news article closing time this will instruct that during the compile time haskell will the haskell compiler will generate from and two JSON instances for the news article and I'm happy with the default options because I'm just storing this into data based loading it in the database it will never leave the server so I'm not that much concerned how the how the JSON actually looks like if you wanted to optimize things you could even turn it and every field into a single letter unique single letter of course because that would say for the type of space but I don't think that there's a difference in this case and it would offer off-fuskete JSON select variable you will it won't be humorable at that point at all so now we have news articles on the server side but these aren't really I mean these are useful already but these are not really useful for the players because players need to be able to read these articles so we need to turn them into the surprise JSON and sent them into the over the wire to the client side and here comes the first problem so the big problem that I was fighting for quite a long time it's type and type class instance form a unique player so you can't have multiple declarations of the same type class for any type if you in all case because we have two and from JSON instance it defined our for our news article we cannot define a new one so there are three options we can do here we could send the same data to client that gets to storing the database and I didn't want to do this to this because it would tighter serve a client and the database two times to get there I could create a new type that is identical to there this news article it will basically distract the news article and then I could define the two and from JSON instances for that new type oh I could just declare and completely new type that has no relation whatsoever to these news articles just copy data over there and then turn it into JSON use that that our object for common editing with the client basically our data transfer object I went for the third option because it's the most flexible and I was asked to have some extra data here the that is not present on the database but it's derived from somewhere somewhere else and this is one part where quite a bit of complexity comes from so first the first is to define our data types and collaborating on the client found it is here again but every other news is working the same way so these are pretty much copies so we had a news article data so now we have news article DTO and it has a value constructor star front DTO when on the earlier it has a sort of planet front DTO and it has a single parameter planet front news DTO and it was planet front news earlier and then the planet front news DTO is a record type that holds in this identical data to that planet front news and in theory I could have extra data here already but not in this particular case so we need a way to move data between this this I don't know real news articles and this DTO object and I decided to implement our data type class for that to then generalize things and this time class is written as a class parent 2.0 DTO CD5 CROD where and then to DTO double colon CROD they have then properly done like much since when heard over the audio it might if you if you have a chance now could go down to check the show notes now basically what is tells us is that we have a type class to DTO that takes two parameters C and D and the D parameter has to implement two JSON by one it has to have an instance of two JSON by class meaning that this whatever D is can be turned into the JSON and it also tells that because it's a multi-parameter type class it also tells that if you know the C you automatically know the D that C is what defines the D meaning that for any C it is only one D and it defines it as one function to DTO that take form parameters C and produce as a value of D and these are this type thing I think is the what the class that it is that C defines the type of C define the type of D is called a functional dependency and without it is compare might or might not be able to the D to D depending on the context so is the code that follows after the code to JSON doesn't use for example doesn't use the specific values of the of fields of the D if it's a very generic use only using some for example are type class functions defined in the type class the compiler might not be able to reduce what the D is so that's why I'm using a functional dependency here I'm including a pollinx into the show notes that the more about this and explain it in more detail the detail so then just have to write instances to all of our new article and new article DTO times that E that are defined the instances of the DTO this basically are just copy copying over data from one side to another and I'm not going to read that out because it's a boring it's a striking the plain planet name of the DTO E equals to the name of the new article and the system name of the DTO E equals to the system name of the article and just I'm happy it I'm fairly confident that if one would know template has got to take us out of 90 spot completely I don't know if so I had to buy it by hand and the final final step is that I've wrapped this up with a new CDO that has a common data that data that is common to the old news articles so here we have a primary key news DTO ID and then we have the content this way that this is part where you put the for example blind found this DTO and the icon as a text because I didn't want to code on the client's hardcore data that when we are showing a planet one news we are using this icon we are going to give on the on this data that gets done into the JSON or URL to icon that is specifically the news icon news article and then the client's side can decide to use or not use the phone so how do we are getting these icons so our DTO instant hand has answered that so instance instant of mapping from the top of key news news article we are nothing from a top of the third parameter is that key news news article top of the second parameter is the icon marker news article DTO and this icon marker is something that knows how to turn out to tell that if any key news article DTO this is the URL where you will find the icon that you can use to display it and yeah parameterizing the icon marker because you might have another case you may be want to use the icon marker for some of the news that the user use a road the probability and different logic to figure out which icon to use so with this one the manufacturing of news DTO is a result of the manufacturing news DTO where we can say that the ID is the ID of that news article the content is the content and the news icon is run icon marker icons content to the content is the DTO that in this case defines what kind of I want to use so what is our icon marker actually this this I'm this part I'm pretty happy this turned out to be pretty nice in my opinion so icon marker is a new type meaning it's a in this case it's a I record of a one one field so new types can only have a one one one type parameter I mean sorry one parameter to the value constructor all one parameter in if they are at the record and this is a record has a one field run icon marker that is of type A to text and this A comes from the parameter from the type parameter of the icon marker so whatever type of the icon that we are having we can use that type and turn it into the text and then we just agree that that text will be linked to the URL for example in the news article DTO there's a case function there are case structure saying that case article off planet planet found DTO arrow so being is meaning that when we are dealing with the planet found DTO we are in turning off the value render dollar static or image is underscore news underscore planet underscore bnc so this well the way the has got deals deals with the resources instead they are actually present at the compile times and they turned into pipes so when I have in my static in my in my static folder folder code static there's a folder code image is there's a folder code news and in that folder there's a planet dot bnc file that gets turned into the type code images underscore news underscore planet underscore bnc meaning that I can refer to that with static all that turns into the root and compiler will catch if I missed my bit or the resource is represented during the compile by and render function will take this root and turn that into the turn that into a text it will tell that if you are talking about this type the food in this particular case the URL of it is this text and this is something that are yes or thus for us and you can get that render function with get URL it gets URL render function call so back to Jason now that we have icon figure and go back to the Jason so now we have a data transfer object that is completely filled out in answer it has our news article inside of it sorry it has our news article detail inside of it and it has the icon and it is the ID the data place it came from we need to turn that into the Jason and I've wrote the two Jason and from Jason instances by hand because I'll I wonder how the full point role of what the Jason looks like because I want to send nice looking Jason to the client because it's nice to work with and it's just all I think to do and not to make life of the whoever is writing the client hard I could have I could have used the template haskell for some of them because you can you can for example you can write your own function that tells tells do the template haskell to how to how to see if names are correct for example but I I went just when then wrote all this by I just went and write all this out by hand I think it's a good access to do that once or twice and when you understand fully how things are working then you can start moving into template haskell and thinking that is you could have a little bit of this thing here so we are actually just creating a Jason that has fields ID the contest ID again content content content that actual visual article video third interpretation then it has a tag that is just a thing that specifies which type of news we are dealing with so the client factors and have to guess and start figure out that we have three fields so what kind of article did it mind this might be it has icon that is a link to that icon and it has started telling the which date the news articles written and yeah so time to put all of it together so in the handle function this is the function that actually handles the incoming HDTV request to that that controls that we define in the config roots character of file so it's got get ip message r the name name of the root in the config file was ip message r and the get in the beginning of the file that this handles the get request and it has a two lines first one is a you know parenthesis underscore comma underscore comma f ID parenthesis arrow to the left happy record record function this is a this is what does the authentication it checks that the user has locked in and that they are meant of a fraction if they are not a member of a fraction or if they are not a if they have not locked in they will be given a appropriate HDTV request one setting 300 400 400 400 is the correct print for all three I think is that not authorized I don't remember that from top of my head and in and in the body of that response there's an explanation in a JSON what what went for and then then the our next line is load all messages FID meaning that we are loading all the messages specific to our given section and loading all the messages is basically just switching over the database yeah we are loading all the news that are forced to get for the given section and that has not been marked right already and so the discounting for a new state so the newest ones are written first this is the part is made in the query I have that news dismissed equals equals on comma false this is the in the future I want to have a system that instead of controlling if the news has been read instead of controlling that with a single field in the database because it's a fraction white I want to have a bit more logic so that they are using the identity of the locked in user and leaving from a separate table that what entries has this user already marked as I said and use that information to filter out what data we are returning to the user but that's for the future there was some there's so many things to do that something just has to wait for another day so this is a loaded message this is our entities this is a list of entities and we need luckily we have a parse news entities function that we can use to turn this into the parse message now we have a list of defaults at first item is a key and the second item is a news article then we grab the request render function it's a render arrow to the left get URL render so here's a thing the parse message is a now the parse news entities is a so-called view function it only depends on the data that you are given to it is a parameter and it only returns data it does not do anything else so that's why we have to use let value equals to the function call but get URL render is a monotid function meaning that it has a context on which it works and that context for example contains well it can contain whatever as people put into that context and there's lots of different things and different ways of dealing with context but in this context in this case the context is used to reach for the configuration that tells in which address this cell is running so that we can turn so that we can have a function that can turn our static food into the actual URL that's why we are using the arrow to the left yeah i would love to be able to explain it detail how how how the whole monotid thing works but true to be told it's a it's super super simple thing and it's just simple thing that it's awfully hard to explain well that's a gazillion or even more tutorials on the internet all trying to explain what monots are and most of them are failing horrible because they are using a not anecdotes but they are trying to simplify things and they are trying to use it samples that are not really cool examples and they are all i'm saying that if you don't understand them don't worry because if you keep using them from the you just realize that this is awfully easy and simple but they are awfully hard to explain well and to be able to use them doesn't really require you to understand the theoretical foundation so I don't understand all of that stuff either just use them so now that we have that render function we can measure you are icon map that is used for the user icons and thing we can see that though another icon map that is used for that is these article details the reason we are using two icon map is that the user written news has their own logic that dictates with what's icon which icon to use and the news article detail and news article details different kinds of logic and because the user written news are part of the news article news articles we have to have this two level structure that together understand how to deal with all these special cases and here you can see a if you are looking at the show notes here you can see a good example where the point three not as point three style gets into the realm of unreadable gold something in that I should go back and find this out fly this out and see and make it make it more readable because it read to it comes so much into one one it reads as a written dollar to Jason dollar not open patterns to detail come on no full stop actually open pattern fit open pattern come on close pattern open pattern icon that the render user icons points of close patterns parts parts messages so what this does is that it feels it will take those past messages turn them into the first first our construct our top also out of them so that you have a top full of our news entity sorry icon also ID and the news article and then the second second item in the top is the icon marker and then that is said to the 2DTO so that you get a data transfer object from that and then that you turn that into the you do that to hold this stuff hard in the of course articles and then you turn all of them into the to Jason and then you return that data to the client finally so that's basically what happens when you're loading the news articles and this what according is a long enough order I'm sorry about that so I'm gonna I can't go into the how the deleting and posting this work well I can quickly over them deleting is basically just you authenticate the user and then you use the parameter that they passed as a passed as a part of the URL to load a news article from the data and actually you don't even need to load a news article it's just delete that news article from the data first delete a row where the ID and ID equal equals to that passed test in ID and the fraction ID equals to the fraction ID of the locked in user is because if you're not including the fraction ID the player could be deleting out of actions news and that we can have posting a news entry is tell you authenticate then you read the body of the request that should contain a JSON and then turn this into the news article and this is basically a reverse reverse operation to hold the thing that we just went through and then you save it into the database and found that is to load all of the entries from the database turning into JSON accident that into the two clients okay I think that about it if you have any questions comments ideas I will be happy to hear them and the easiest way to catch me nowadays is either yeah email that's I think that's our visual attack and a hacker property radio page or at the very least where I am I am a tutorial at Masterton that's also so so I am Tukadurta adhashpura you've been listening to hacker public radio as hacker public radio dot org we are a community podcast network that releases shows every weekday Monday through Friday today showed like all our shows was contributed by a HBO artist near like yourself if you ever thought of recording a podcast and click on our contributing to find out how easy it really is. HECK a public radio was found by the digital dot account and the informomicon computer club and it's part of the binary revolution at bnref.com if you have comments on today's show please email the host directly leave a comment on the website or record a follow up episode yourself unless otherwise status today's show is released on the creative comments attribution share a light for the dot org license