 I'm Chris. Most of my contributions to the Haskell community centered around helping people learn Haskell. This title, that's how long it took me. I am not particularly smart, but I can empathize with how hard it is for people. Now, to be fair, this isn't steady progress. I kept bouncing off the surface. Kept trying to come back. And I just want to talk about why this seems to be common, at least to me, among people who try to learn Haskell. And does this need to happen? I'm not going to teach you Haskell in this talk. That was yesterday. If you missed it, I'm sorry. Yesterday was fan service. I'm not going to teach you how to teach Haskell. Takes too long. The best way to do that is to hang out in the IRC channel, Haskell Beginners, on a free note. It's not even me teaching. Other people do an amazing job there. I don't even have time to teach there anymore. You can learn from them. They're great. I'm not going to convince you to learn Haskell. Sorry, just kind of an axiomatic assumption, like we're talking about learning Haskell. So I'm not here to do sales. And I'm not going to do that on Twitter either, so don't bother. I am going to talk about some of the problems I had and some of the problems other independent learners have had, which is another kind of key assumption here. I'm talking about independent learners. I didn't go to school. I don't teach at a university. These are all self-learners trying to help each other out. Different assumptions are evolved. Different limitations are involved. So yeah, it took me a long time. My dad bought me a copy of World Haskell back in, like, 0708 print copy. I didn't get very far, partly because I'm lazy, but there are other issues, too. Yeah, skip them like a stone. I kept getting frustrated. I would learn a little bit, and then I would try to do a practical project. And then I wouldn't understand any of the libraries. And I wouldn't understand what was going on. What's this functor thing? Why do I need to care? Why can't I just make it do something? And then I would burn out. Like, there's no way this is practical. Why should I have to care about all this stuff? Why do I have to learn all this stuff? I just want to make a web app, right? So yeah, I'd learn a little bit, fail, because I'd try to do a practical project. Learn a little bit, fail. On and on for about five years. So if you go through this experience, and it's this frustrating, how does anybody use Haskell? How can there possibly be any happy production users of Haskell? Just so you're not in suspense, I use Haskell in production. I'm very happy. There's a happy ending to Disney's story, but you do start to wonder eventually, right? Like, do they all have really high IQs? Like, what's going on? Maybe there's a secret Haskell cabal? Oh, no, that's the package manager. So I eventually made it. First thing is, I'm going to be honest. The way I learned Haskell is not the way I teach Haskell, because I don't want anybody else to have to work that hard. But the important part is to understand the way I teach Haskell is not a reflection of how I learned it. And we have to remember that. Most people have a very big disconnect there. I spent a lot of time bouncing between different resources. If I made people learn Haskell the way I learned it, probably at least a year. For some people, maybe slower people like me, five years. So I've been teaching Haskell for about two years, but you should be aware that at the beginning of those two years, I was really bad. Really, really bad. One of the first people I gave a tutorial to on Functor Applicative Monad, his company now uses Haskell, but he did all the work. What I taught him was almost useless. It was terrible. I'm glad he forgives me. Basically, he was my test subject. He was my victim. But we also have to be aware of that. When we're first starting out teaching, we don't have students. We have victims. We owe them, not the other way around, for giving us their time. These days, I do in-person tutorials. I give talks at meet-ups. I help people via email, IRC. I pop into Skype and Hangout sometimes to do a quick 30, 40-minute sprint through something they're stuck on. This is partly so I get better at teaching. Oh, I should explain the motivation. I started teaching Haskell because I knew that I wasn't going to be able to use Haskell at work unless I could train my own coworkers. Because otherwise, what am I going to do? Tell them to go Google. And then they go through the same five years I did. We're not going to get to use Haskell at work if they do that. So I had to know how to train people in order to use the tools that I wanted to use. So I had to take responsibility for educating myself and other people. Turns out, I actually just kind of like teaching. That was an accident. I didn't actually, that wasn't the plan. As I said earlier, some very experienced people who are much better at teaching than I am even. In Haskell beginners, there's people that are doing their PhD, just self-taught people that have no affiliation, really diverse group, amazing people. Very nice. And we run a pretty tight ship on there. It's not quite the open fray that some other IRC channels are. You're either getting help or you're helping. That's it. I started the guide about a year ago. This was partly so I didn't have to keep like, OK, do this, then that, then that, and keep writing it out over and over. But again, this is not just me. The guide is input from other people that are also teaching other people Haskell. The core recommendations, I didn't write either of those courses. I didn't write CS1 and 4, and I didn't write NICDA course. NICDA course I found out about through the Australian Haskell Hacker community, and I also found about CS1 and 4 from the Australian Haskell Hacker community. By the way, the Australian Haskellers are amazing. If you get a chance to talk to any of them over the internet or Twitter, please do so. They're really nice people. And it's been translated. German, French, Spanish, Italian, and Portuguese by volunteers. So now people that aren't totally comfortable in English, it's listed right at the top of the guide. Your light in your own language, go here. They do trail a little bit because I have a habit of changing things too much, but they're there. So the core recommendation is to do CS1 and 4, Spring 13 specifically. I know. I know. I know there's newer ones. I know. I check them every time they get pushed. Followed by the NICDA course. I used to just recommend the NICDA course. I don't want to drive people to depression, so we warm up with CS1 and 4 now. NICDA course is amazing, but it was designed for people getting an in-person tutorial. So you're running through exercises, but you're not doing it in your own. You're getting help. So when the tutor sees you get stuck, they can help you get unstuck and figure out how to wiggle into what you're having problems with. When you're learning independently, you don't have this bidirectional exchange of information. They have to just try to anticipate everything upfront. That's really hard. So that's partly why the IRC channel, to help people get unstuck. It's also partly why we have to warm up with CS1 and 4. And the recommendations, they don't go in the guide unless I've tested them. And I don't mean on myself. I already know Haskell. That doesn't do any good. That's not data. That's just a person reading. We test it with people learning Haskell before it gets recommended to anybody. This is important. You do not know how difficult it is if you've been doing this for any length of time. You do not know how effective it's going to be upfront. You have to collect data. I know the end can't be that large. There are limitations, but you need to at least try. It's very important that you test your learning materials. And everything in the guide is subject to getting removed, modified, or replaced. If somebody makes a better CS1 and 4, it'll go up. Right now, the newer versions of CS1 and 4, they're good. But they're not appropriate for a beginner's introduction to Haskell. They cover some more intermediate material, which is great. But I think they're covering some of the more beginner stuff in a different class. Now I have to tell them, like, do a couple of sections here, a couple of sections there. I'm not going to do that. The more complicated the guide is, the more people just start ignoring it. So yeah, there's no control group. I'm not claiming to be scientific in this process. I just have to try to run people through stuff, get feedback, try to find out what works, try to identify some patterns. I'm not a scientist. I'm sorry. I don't have enough volunteers to do that. Even if I did, I wouldn't know how to design a proper educational experiment. There's a lot to learn from the university classes, but the situation is very different. As an example, UT, University of Texas, Austin, they have a class where you learn Haskell. It's their PL class, but that's not a first or second year class. You cannot assume a self-learner's had two years of CS education, like just a moment ago. Even if they've had a CS education, how do you know it was the last year? What if it's 20 years later? Are they going to remember everything? You can't assume that. So there's a lot to learn, but it all has to be kind of run through this transmogrifier of, well, but we can't do that because we can't assume that. Some of the people learning Haskell, through the guide, through the IRC community, some of them are students. Some of them are bored with their classes and want to learn something more interesting. But again, you don't know where they're at. So one of the patterns with Haskell learning materials, and this applies to some of the books as well, they have this pattern doing show, don't tell. That's a good start. That's not good enough. If you don't make them write code, and if you don't exercise their ability to synthesize what you've showed them, you have to assume it will go in, out, gone. It won't stick. What you're going to do is you're going to plant some seeds for later. But all the pain is going to happen all at once when they go to try to apply that knowledge. That's not what you want. If you front load all the pain at once, they're going to burn out and they're going to quit. And you just lost another Haskell user. You cannot do that. You have to try to figure out an even ramp. You also want to reinforce proximal to the material you're introducing as much as possible anyway. So you want to, you know, OK, we showed you this. Do a bit with it. Show you this. Do a bit with it. Use the keyword. Don't just show them. Show them, too. But showing them is part of the explanation. That's not an exercise. The exercise follows after that. Good example. So you want to iterate and have exercises that iterate over a theme. It's fine to explain case, guards, if and else separately. We do in our book. But you need to make them reintegrate it and see how they compare. What's similar? What's different? Make them write the same function in two, three different ways. They aren't going to know how everything relates unless you make them do that. If you don't do that, they have to do it later all at once. Then they're going to get frustrated. Then they're going to give up. Then you lost another Haskell user. OK, so I kind of alluded to this. Most people believe that the way they teach Haskell is the way they learned it. I think there are reasons for this. It's usually not true. Most people have created a narrative around how they learned things that is mostly not true. I'm not saying they're liars. Everybody walks around with all kinds of self-delusions. Like, I believe I'm a nice person. That's totally not true. But I need to believe it so I can sleep. My dog likes me. It's good enough. So my dog's a nice person. So we create these narratives around how we learn things. We believe we're the super brainy roughman. Well, OK, it depends on your cultural background. I guess in academia it's different. But definitely among the self-learners, one of the anti-patterns, if you will, is they believe that the rough and tumble Haskell, well, not Haskell civilly, just hacker it, figure it out, and did it all themselves. Yeah, that's nonsense. I've seen all the questions that people have to go through on IRC and mailing us. Getting help is good just to be clear. But don't tell yourself that you didn't get help. You did. You got a lot. Some of it was synchronous. Talking to somebody. Some of it was asynchronous. Expository explanations in addition to some core course. Like, you're reading something in a book. The explanation didn't make sense. What the hell is this functor stuff? I don't understand it. They're just showing me some code, and I don't know what's going on. Then they proceed to Google and go through a bunch of other functor explanations. Then they understand it. But what are they going to tell the next person that wants to learn functor? Oh, I read this book. That's not true. That's not the whole truth. And it's important that we understand that's not the whole truth. Because otherwise, the recommendations we're giving people are subjecting them to the same pain that we've already gone through. And that's not necessary. We can fix that. Fetish and myth. So this is kind of specific to Haskell. It might be kind of specific to FP in general. We fetishize difficult materials. This really has to stop. This is bad. We are fetishizing materials just because it makes us look smarter. That is a tremendous waste of people's time. There is an essential difficulty ramp to these materials. Don't get me wrong. Fixed points. Figuring out how to pull a fixed point out of a data type instead of direct self-recursion in the data type. That's definitely that takes a leap beyond just a recursively defined data type. So there is, in some sense, an elaboration. Is it more difficult? I don't know. Maybe once you've gotten recursion, it's not a big deal. But there is an elaboration there. But does this mean that the only resources on this topic should be white papers? They're dense with jargon that they're not going to know? I'm not saying these papers aren't valuable, but they're not written for self-learners or for your typical working programmer for that matter. I'm also not saying that we should bold-reise our terminology. You will never hear me call functor mapable. There is a specific reason for this. The names we use for things are not an opportunity for branding exercises. I'm not going to rebrand functor and be like, hey, look, I've invented a computation expression or some nonsense. No. It's a monad. It has a history. You need to be able to know how to look it up. If I give it a new name, you can't find any of the history of it. I have wiped your ability to find out the entire genealogy of that topic. And I've deprived you of the opportunity to deepen your understanding. That is also just, in my opinion, totally unacceptable. And that has to stop. We have to tell them where to find out more. We don't have to tell them all at once. We don't have to tell them one resource. But citations, footnotes, more here, something like that. That would be great. That would be an immense help. Like, you write about a topic. I use these papers to write about this topic, learn more here. Stuff like, Hasslers often want to learn category theory, because I think they need to. I'm not really an authoritarian category theory. I don't understand category theory. But I will say that I am a happy and productive user of Haskell, who was able to understand the advanced talks that I've seen so far with no true meaningful understanding of category theory. So at least to that extent, we can say that it's not strictly necessary. I do think it informs a lot of new developments in Haskell. So if you want to be on the frontier and develop new interesting stuff, it helps to know what's already been done. Category theory is very important for that. But if you just want to use Haskell or some similar language, not that there's very many that are like Haskell, you don't need to learn category theory. You don't. But if you want to, awesome. But yeah, like recommending the claims, you're wasting their time. That was written for grad students who've just gone through a bunch of mathematics and education. This is like buying the art of programming and leaving it on your bookshelf. That's not how you learn category theory, unless you're a grad student, but you're not. So don't. Don't do that. I mean, unless you know your audience really well and you know they're actually going to be able to handle the book. There's always caveats, but come on. So yeah, we recommend material that makes us look smart. Like, oh, I learned it using the super hard thing, when really the truth is I read some blog articles about category theory. You're not helping people when you do that. You have to get off the happy path. Haskell, in my opinion, has good type errors for people who understand them and are used to them. For beginners, there are some problems. Simon Payton-Jones knows about these problems. He would love it if somebody worked on that, worked on making the existing errors more beginner-friendly. And they've even posited the idea of having a beginner's mode that would add helpful suggestions, like maybe this is happening. Maybe you made this mistake, that kind of thing. But when you're introducing people to a concept or some syntactic construction, you need to anticipate what they might get wrong. What if they mistyped this? What if they forget a bracket? What error did they get? Is it gonna say syntax error, or is it gonna give them a bogus type error? You can't anticipate everything, but you need to get off the happy path sometimes, show them what it looks like, explain the type error, and why it may not sound like it's about what they actually did wrong. Yeah, you... My co-author has been adding a lot of the non-happy path stuff, partly because she has a bit more proximity to having these confusions. She's done a great job on those so far. So, yeah, you have to get off the happy path. So, I mean, the guy that put together, I only know if somebody had a problem if they come and tell me, right? I mean, I have my own personal experiences learning Haskell. I worked with my co-author and helped her learn Haskell. These days, she's really just learning it from the book as she goes though, which is good because that tests the material in addition to the other people we test with. But if we don't know, then we don't know. There's any number of unbounded people dropping out, failing, having problems with the learning material and we just don't know. So that's another problem. I chose to optimize minimizing the rate at which people drop out. Basically trying to optimize for avoiding burnout. That's the main consideration. Just keep them going. If it takes them one month to learn Haskell, well enough to use it, fine. Three months, fine. Six months, fine. Whatever, whatever it takes. Assuming you're not gonna quit programming in the next year, probably worth your while to learn Haskell. That's not a sales pitch. Just an ROI. Another problem is that some of the most well-known materials for learning Haskell are nowhere, they're not really in the top five. This is a problem because now the onus is on you to explain to them why they shouldn't use the popular thing. Fair, fair. So I wrote a whole blog post about it. Now some authors on Twitter are angry at me. Fine. I'd be happy to work with anybody whose work I've criticized to help them improve it. I would be happy to. Nobody's taken me up on that yet. I'm not naming names. I'm not doing that, sorry. I have a blog post. I go over it in detail. And in that context, I also mentioned pros. So that softens it a bit. Because every resource does have good points. Just be clear. Every resource does have good points, but I can't craft a path for learning Haskell by cherry picking page numbers out of 10 different resources. That's ludicrous, I'm not gonna do that. I'm not gonna expect the readers to do that either. So another problem is that most authors, and I understand why, being in the middle of writing a book myself, they craft one explanation for a topic. But what did I mention earlier? You read the explanation in the book about functor. You reach the end of the chapter about functor. You still don't understand functor. Now you have to go Google other resources and explanations. My hypothesis, and this is not well established, is that people just need to see things from different angles before they really feel like they get it. Sometimes they actually understand it and just don't believe they do. Sometimes they actually don't understand it. Another important part here is you need to, so just as I talked about getting off the happy path, you need to craft with positive and negative space, just like design. It's not enough to show them what's good and what works. You need to anticipate what they're gonna do wrong, what they may want to do because they're just not familiar with it and it isn't good or wrong or some kind of misunderstanding and you need to actively target that and excise it and show them why that's not true. If you don't do that, it just lurks and then you get people thinking functors are just things like lists. They're not, not at all. So the single explanation problem, I'll have a thing up here in a moment to show you why that's a problem. But I don't think Haskell is particularly difficult to use. I don't think it really needs to be all that difficult to learn. I do think there is a high novelty associated with it relative to the programming languages you already learned. If you go from Python to JavaScript, what are you really learning? Syntax? Most people don't use prototypes, so don't tell me that makes a difference. What is it? You call it an object instead of a dictionary? How much is really new there? I'm not trying to make fun of the languages, I'm just, let's be honest. How many new concepts are they actually learning? Now if you go from JavaScript to Haskell, what are they learning? Everything, from the ground up. You're learning how to program. So you might as well just write Haskell books as if they're learning how to program, because they are. There's no point in making any analogies, they won't make sense. So that's why we're writing our book for non-programmers. There's no point, we can't reuse anything, so we'll just assume you don't know how to program. So most resources don't use best known effective explanations for most things. They do have bright spots, some are better than others. For example, here I'll call out a name and give you a strong example. Hutton's book has really good material and parser combinators, really good. So again, the goal here is to prevent dropout. We're also assuming that the people aren't gonna ask us for help every time they get stuck. So we want people to be able to continue to make progress without having to ask for help, ideally, ideally. It's okay to ask for help. We're just trying to make things easier. Now, if I provide one explanation or one demonstration of each of these concepts, is that one explanation gonna work 100% of the time? No? So what happens if it works 80% of the time? 80% would actually be a tremendous success. If you have an explanation that works the first time, 80% of the time, you have written some truly masterful material. Really. But what's the problem here? They don't have to learn one thing when they go to Haskell. Right? Lots of novelty. Novelty in a good way. It's different, right? But there is a lot to learn. Lots of stuff that isn't familiar, stuff that doesn't have a sensible analogy to what they already know. So the problem is, is that by the time we run these people through these 80% filters over and over, we're down to 60% of our cohort. That's not good. That sucks. They're gonna be really, and the 16%, they're probably really frustrated already. And they haven't even written a web app. Rails can make a web app in five minutes. Why can't we in Haskell, right? I'll give you a hint, it's because you're typing Rails new, not because you're actually programming. Anyway, so how do we avoid this? Well, we avoid this by having elaboration. You attack it from different angles. And you try to figure out different ways of thinking about the same thing, but you ideally want to avoid analogies and things that aren't strictly true. It is more permissible, in my experience, to use approximate explanations earlier in the process of explaining a concept than later. So if you want to make the analogy that functors are about containers or lists or something, keep that early. But try to work on excising out the bad parts of that explanation later. Try to show them how that's not really true. Or you could just skip the lying to them part. Anyway, so things here worse with functor applicative and monad. I'm gonna pick out IO. How many people here know how IO works in Haskell? Oh, we have a couple. All right, really more than expected. You're that or you're really honest crowd. All right, so here's the problem. One problem is that some resources will introduce IO and monad at the same time. They're not really related. Yes, IO and monad were introduced to the programming language at the same time, but conceptually, there's no meaning there. IO as a data type doesn't do anything semantically. It only does things operationally. Part of the problem with these explanations about IO in terms of monad is they don't actually tell you anything about what IO does because the IO and monad doesn't actually do anything. For the purposes of a strict beginner, they can pretend its identity and it doesn't do anything. That's not, there's operational differences, but what does that have to do with monad? That's to do the type, not the interface you use to work with the type. So you need to uncleave these things. Another problem with these explanations is that if I tell you that Haskell can perform side effects because an IO call is a prayer to the Sun God Ra who will then inject the side effecting code, that is approximately as true and useful as most of the explanations of IO I've seen. If your explanation does not give them the ability to predict what code does when it does or does not have IO at the end of the type and I don't mean the presence of side effects, I mean the operational difference, don't bother, don't even say anything. Just pretend its identity because for their purposes it is. It doesn't matter. Either your explanation provides explanatory power and explanatory power means they can read it and predict what it will do without executing it because that's the whole point of this type thing, right? We should be able to just read code and know what it does. So if your explanation is not in service of that faculty, drop it, there's no point. You'll just be wasting their time and yours. So there were a lot of Haskell resources written in the 90s that were actually pretty damn good but they were written in the 90s. Why is this a problem? Well, Haskellers really like discovering new things that are useful and that's great. That's a good thing. We should have languages they're able to evolve. However, practice has gotten ahead of pedagogy. Even this, functor-replicative monad? It's a good start. You're still gonna need no monad transformers if you write a web app, probably, unless you use something that just slaps on my own, everything, but you could. And I actually think that's valid, by the way, like when you write your first web app after learning some Haskell, keep it simple. Don't try to go for maximum fanciness. Keep it simple. But yeah, practice has gotten ahead of a lot of our learning resources that were already really good. So the problem is how do we connect the dots, right? We've gotta catch up. One thing to consider is that monad's been around in Haskell for a while, since 93, I think. That was before it was a type class, which is syntactic. But applicative? Not really a thing until 2008. Real-world Haskell was written before that. Implicit is pretty important. But it's important not just because of how we use it. It's actually important because it actually helps with the understanding of the whole functor-replicative monad thing. It's less of a leap from functor to monad that way. So I recommend CS104, Nick, the course because it's a compromise between appropriateness, thoroughness, and it covers what you need to know. Also, the other reason I recommend this is because they have exercises, kind of a low bar, but the exercise is actually pretty good. They are difficult, and I don't consider that a plus, unless it's truly necessary, but it works. So another thing that people don't seem to understand is that Haskell kind of builds on things. It has a pretty orthogonal design. This is great. It makes the design simpler, more unified, cleaner, but it does mean that things kind of build on top of each other because we're not just like baking special syntax for every new thing that we invent in Haskell. We're using the primitives that are already available to us. So what do you need to understand to understand functor? Data constructors, type constructors, functions, function composition, some types, product type, and I did forget something, type classes? Constructor classes, who here knows what I mean by constructor class? Oh, nobody's read the classics, all right. So, constructor classes were invented in Gopher. It was a dialect, I guess, of Haskell. It was an alternative implementation. The author of Gopher, pioneered constructor classes constructor class is a construct, it's a type class where the instances are not for concrete types, they're for type constructors, thus constructor class. We have since conflated those categories, but that's not how we discovered them. Concrete normal type classes were invented first and then constructor classes came later. It's fine to refer to them generically as type classes, but we need to aware that this is actually a leap. This is an elaboration that we need to call out as being distinct when we're explaining things. We can't just take it for granted that it's the same thing, it's not. You have a higher kind of type for your type variable for the class, that's different, that requires explanation. So, sometimes the history can help understand like how we can convey these things. So, you can use the hand wave explanation. For all functor f, map over list is kind of like f map over whatever your f is, but I'm not fond of it, but I know why people use it. And again, earlier, okay, but your understanding of functor does not end there. It begins there. If that's your understanding of functor, not denigrating anybody, but you've started, that's good. Keep going. So, it's dangerous if all you tell them, but if it's just a bootstrap for a more detailed and accurate explanation, fine. As long as you're making it clear that it's not strictly true. Well, it's true in a lexical sense because you're kind of just swapping up the types instructor and you know, but we don't worry about that. So, all right, why is the hand wave problematic? Because there are valid functor instances which are perfectly law abiding, which contradicts this intuition, right? And intuitions are useful. That's another thing. We don't work backwards from formal definitions. That's not how human beings learn. I'm just gonna go ahead and point a flag in the ground here. We work our way towards formal explanations from informal experiences with those structures. You build your way up. They develop some familiarity. You tell them how the formalization works, then they understand the formalization. You can't just drop an equation on somebody and be like, deal with it. That's not education, that's definition. That's a dictionary. So, don't believe you're helping somebody by doing that. But, so intuitions are good. This is how we build our way towards a more principled and accurate understanding of what we're working with. But, we want our intuitions to be accurate, right? Does the intuition of the functor is kind of listy? Hold for the const type? What happens to our F? Are we doing it with F? Or F the argument, not the functor F? Nothing. So, if we think a functor is being like list, this doesn't really work. Because, we're only allowed to not apply that function because B is phantom. If like list, the type variable we're mapping over has a witness in the type, we are obligated by the type system to use that function to produce the value of a new type. It won't let us do anything else. But, I can just work with this all simple example and we can see how that's not really true. So, what is functor really? I'm a little more unfair than I should be here. But, so, equating functor with collection containers, it'll deprive them of some nicer, more useful intuitions of where they're gonna find a functor and what a functor is. It works okay, because to be honest, like a lot of the functors and the stuff we map over in Haskell, a lot of them just look like ASTs anyway. Because, you're modeling some domain, the domain ends up looking kinda like a grammar, the grammar's basically an AST, right? That's a lot of like business logic in Haskell. So, that intuition kinda holds, like a tree basically. So, that's okay, it goes, it takes you places, just not everywhere. But, examples aren't enough for functor either. It's a good start. But, they've gotta do more than that. Try to stick to the facts. Again, the hand waves penalized them in your mind when you're working out how to write something. Like, associate a cost with introducing an approximate explanation. Yeah, cause you'll just end up having to roll it back later and then they're frustrated cause something they thought was true wasn't. So, make certain the bootstraps kinda paying for itself. So, I've already talked about category three. I'm not an authority on it anyway. Don't listen to me about that. So, what do we need to do to learn functor? At least as far as Haskell's concerned. I'm not talking about category three. Examples that work, examples that don't work, examples they need to fix that are broken. Remember Happy Path? Write lots of functor instances for data types. Write lots of code that commends the use of fMap. Invent data types that need a functor. Different angles. If you are simply told something, you're probably not gonna learn it. If you're here, read Reddit. I'll admit it. Haskell subreddit's not bad. Who reads hacker news? I really need to know about that. Okay, do I have any lobsters in here? Ah, there we go, cool. All right. Okay, those are great communities, especially lobsters in the Haskell subreddit. But what do you do on those sites? You're reading, right? Have you ever thought to yourself, oh, I just learned something? Can you think of anything right now that you learned from those sites that you just read? I can't, hmm? That's news. Fair point. So news announcements, all right. But like learning a concept, if I write a post about a functor on my blog and I post it to lobsters, or hacker news, or Reddit, and they just read it, even if I have exercises, they're not gonna do them. So are they gonna remember that? Are they gonna be able to apply that? Are they gonna understand functor? You cannot learn something just from reading it. You have to be doing work. Yes, it takes longer, but you're gonna stop lying to yourself about what you understand. Because the exercises are gonna force you to generate, it's a proof obligation. Prove you understand this. Fill in the proof obligations, right? No proof, no learning. You have to do the work. You have to do the work. It sucks, I know. But it takes less time to just do the work than to spend five years bouncing between blog posts. Quick note about learning learn. Edward Comet gave a really good talk. I think of it at Yowland and Jam last year. You can find it just by the talk name called Stop Treading Water, Learning Learn. Really good talk. It's, I think, reasonably entertaining. You should really check it out. If you're interested in how my co-author and I are teaching Haskell, we've released our book at Haskellbook.com for early access. It is not done. This is for people that wanna contribute, that wanna help us write the book. I know it's a lot to ask, but we're doing this partly because the book's gonna be really long. It's gonna be longer than real-world Haskell, we think. So we need to start testing material with a wider audience now, so that we don't have to do it all once later. And we'd also like to know if we need to reorder things and just kind of change our general approach up front. So, if anything I've said interests you, if you think you'd like to learn Haskell, you'd just like to help us with the book. By all means, check it out. If that doesn't interest you, that's perfectly okay. If you still wanna learn Haskell, you can't afford the book. You don't wanna get a book that's super early because it is right now. Check out my guide. You can get help in not just my channel, but also the Haskell Irish Channel has great people who've spent years teaching this stuff. It's not always the most helpful explanations, but they will help you. Thank you.