It sounds like you had pretty much the same experiences as I had with our course. The course was new and we will only hold it a second time starting end of April, so I don’t have any experience with different approaches, but we have collected some ideas on how to restructure the lecture based on student feedback and exam results (which showed what parts were least understood), maybe some are useful to you.
One student commented that he did not learn as much as he wanted on how to use FP to solve real problems because of too much time learning how to implement the “library” in Scala.
We plan to focus more on an “algebraic” approach, i.e. focusing on the operators a structure like a Monad / Functor / Monoid etc. provides and what laws it obeys, instead of focusing on how to implement it. We will only implement only essential stuff and show usages of those functions instead, leaving other functions as optional exercise. From what I’ve already read, the Cats book seems to be more like that compared to the red book.
Last semester we tried to mix lecture and exercise, having some small 5-minute-exercises of implementing a single function interspersed in the normal lecture (not common in our university, don’t know if this is a usual approach elsewhere). We prepared signatures and required structures in a fiddle. This was well received by the students, but we will probably cut back on the amount of such exercises and/or change what to implement (again, application instead of coding basic building blocks).
As our students did not have experience in any other functional language, most only having learned Java without ever using lambdas, one of the things that the most students had a hard time understanding were Higher Order Functions. We realized this during the State chapter, as many did not understand, where the actual state was in a State monad, because they did not realize, that you pass a function to State’s constructor and not some value of the state’s value type.
It will be a small (maybe 10 students), but difficult group of students, ranging from a third-year undergraduate who probably just has Java plus maybe a little Python and C to several fourth year and graduate students who have had another of my classes that uses Haskell. Most want to learn “multiparadigm” Scala for applications use (e.g., Spark, actors, server-side Web) rather than FP per se.
Our situation is a bit different, we had about 50 students last semester, but also from very different stages of their studys. Additionaly, we also had math students in our course, so we had the full range from “want to learn practical Scala” to “want to learn pure FP and correctnes proofs”). That’s why we will start the lecture with a bit of historic background and lambda calculus next time, as several students said they missed that.
But, as a hybrid (“multiparadigm” is the term I typically use), Scala does not force the students to think functionally. They can fall back back easily on imperative ways of thinking.
We thought of using a compiler plugin, probably WartRemover, to restrict Scala more for the exercises. This can at least prevent usage of
vars and some other not referentially transparent parts. We provide an sbt file anyway, as we use kind-projector for type lambdas in the later chapters, and have an automatic online grading system, so the students don’t submit code which would not pass with that sbt config.