I would recommend having a look at Purescript too. One of the very nice things about Purescript is that it generates
very readable Javascript. One of the things I was always wondering about is how exactly tail call optimisation works. Looking at the output of Purescript for about 10 seconds answered any questions I had.
Also, though it has been posted here before (and I don't think it has been worked on for a while), I recommend playing with the Monad Challenges[0]. Well, specifically, just do set one (random numbers). You can easily write your own rand function that returns the seed value as a "random" number and then increments the seed. This will generate successive integers (1,2,3,4...). It makes it very easy to test. Then once you've done set one, go back and write map, apply, etc for Gen. One other nice thing you can do is to make a union type/ADT for your random number (i.e., (Int, Seed) ) and then try to see if it is a functor and applicative (also try to understand why or why not). Finally, you can figure out why Gen is structured the way it is.
I've played with that kata over and over and over again. It is simply beautiful.
[0] - http://mightybyte.github.io/monad-challenges/