# Learn Monads by Refactor. A Challenge for Beginners

**URL:** <https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216>\
**Category:** Show and Tell\
**Created:** [October 24, 2022, 7:56pm UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216 "2022-10-24T19:56:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lsmor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/lsmor/32/3302_2.png) [@Lsmor](https://discourse.haskell.org/u/Lsmor)\
**Post date:** [October 24, 2022, 7:56pm UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216/1 "2022-10-24T19:56:41Z")

</div>

Hi!

I’d like to share a little repo/exercise I build to help new commers. It consists of building the snake game in Haskell. Nothing fancy: no ncurses or frontend, just spit out a bytestring to the console in the shape of a snake board.

The challenge aims to teach monads refactoring your code, so you build the application twice, first using a pure implementation with all plain regular functions (arguebly, using some state-monad like functions). Then you refactor so the state pattern becomes very clear. Then you refactor again so the reader pattern emerges, etcetera… Eventually you define your own set of `MonadXXX` defining exactly the interface you want.

Another important aspect is that it doesn’t try to be a tutorial at all. It is a challenge. The student is given a Haskell file with `undefined` function and an explanation of what the function should do. It is up to the student to recollect all the resources and to read the documentation. Refactors are explained in `.markdown` files.

I think this has two main benefits:

- The learner escapes from tutorial hell. The skeleton is given to you, but you have to do your own research
- By writing the application twice I think you stop fearing the monad (at least, Reader and State) as they emerge as sort of “good practise” more than an obscure abstract concept.

By good practise I mean that using `Reader` and `State` actually lead to much better code quality (readability and expressiveness) than useng their “pure” counterparts as they are pretty much just pure functions with different composition (well, any monad actually, but very noticeble in these two). So I think this challenge makes a good work explaining the _why_ instead of the _what_

You can find it [here](https://github.com/lsmor/snake-fury)

---

<div class="post-metadata">

**Author:** ![f-a](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/f-a/32/2740_2.png) [@f-a](https://discourse.haskell.org/u/f-a)\
**Post date:** [October 24, 2022, 8:32pm UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216/2 "2022-10-24T20:32:43Z")

</div>

Quite an interesting idea, “learning by refactoring” is indeed a great way to getting acquainted with new ideas.

Small but: I think it is “architecture” and not “arquitecture”!

---

<div class="post-metadata">

**Author:** ![Lsmor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/lsmor/32/3302_2.png) [@Lsmor](https://discourse.haskell.org/u/Lsmor)\
**Post date:** [October 25, 2022, 5:46am UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216/3 "2022-10-25T05:46:42Z")

</div>

> [@f-a](#):
>
> Small but: I think it is “architecture” and not “arquitecture”!

ups… fixed 😅, I am fixing some typos here and there.

---

<div class="post-metadata">

**Author:** ![pdr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/pdr/32/1083_2.png) [@pdr](https://discourse.haskell.org/u/pdr)\
**Post date:** [November 1, 2022, 3:04pm UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216/4 "2022-11-01T15:04:32Z")

</div>

Sounds a lot like: [GitHub - system-f/fp-course: Functional Programming Course](https://github.com/system-f/fp-course)

---

<div class="post-metadata">

**Author:** ![Lsmor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/lsmor/32/3302_2.png) [@Lsmor](https://discourse.haskell.org/u/Lsmor)\
**Post date:** [November 1, 2022, 8:15pm UTC](https://discourse.haskell.org/t/learn-monads-by-refactor-a-challenge-for-beginners/5216/5 "2022-11-01T20:15:34Z")

</div>

`fp-course` is a guided course with self-contained exercises (each exercise is either right or wrong). `snake-fury` is more of a _build a project_ thing. You are given a half-implemented project and you have to implement some functions to make it work.

`snake-fury` makes almost no attempt to explain libraries or concepts, it tells you “hey!, you must use the `array` library to build the Board, go ahead and look its documentation”. That’s why it is a challenge, you are given the type signatures and it is up to the learner to look for the docs/blog/material needed to understand what is going on.

Also `snake-fury` is very focused in introducing concepts via project refactoring. So you are evolving the same code base over and over again with new ideas, which as far as I can tell is not the scope of `fp-course`
