I'm a couple of weeks into dabbling with haskell and I've made a pretty big dent in Learn You A Haskell. I feel like many of the type classes and common implementations up to applicatives and monads make a lot of sense to me and I understand how they work, but I still lack a lot of practical experience.
One thing that kind of irks me, coming from a mostly imperative/OOP background is the concept of values/functions that evaluate to infinite lists. I can of course see how they can be used to write some definitions very tersely and they are surely useful in loads of cases I can't even imagine. I wonder what the common approach is to mitigating their risks though. If you at any point in your code accidentally evaluate an infinite list "fully", your program will just get stuck. This is possible to do in imperative languages too of course (certain implementations of the IEnumerable
/Iterator
interfaces from C#/Java for example), but it's my experience that people rarely do this because it's ... well, dangerous.
One of the big advantages of Haskell is the compile time checks you get. Can we do any compile time checks to deal with this risk? Or do we write tests for it? Or are we simply "never stupid enough to do that, and if we do, we notice it after 1 second when running it in the REPL"? Or are there naming conventions?
I realize this is probably a bit subjective, but surely there are common idioms?
[a]
used as one would useIEnumerable/Iterator
and use more efficient, specialized structures likeVector
's for "small list like things" for efficiency purposes which mitigates a lot of the common issues IMHO