I'm sometimes looking at Scalaz and find it pretty hard to understand for a beginner Scala programmer.
implicit def KleisliCategory[M[_]: Monad]: Category[({type λ[α, β]=Kleisli[M, α, β]})#λ] = new Category[({type λ[α, β]=Kleisli[M, α, β]})#λ] { def id[A] = ☆(_ η) def compose[X, Y, Z](f: Kleisli[M, Y, Z], g: Kleisli[M, X, Y]) = f <=< g } implicit def CokleisliCategory[M[_]: Comonad]: Category[({type λ[α, β]=Cokleisli[M, α, β]})#λ] = new Category[({type λ[α, β]=Cokleisli[M, α, β]})#λ] { def id[A] = ★(_ copure) def compose[X, Y, Z](f: Cokleisli[M, Y, Z], g: Cokleisli[M, X, Y]) = f =<= g }
Scalaz methods may seem obvious for experienced functional programmers, but for anyone else it's hard to understand.
Why is there so few documentation in Scalaz code?
Why do they use so many operators that are unreadable for most people? I don't even know how to type ★
or ☆
without copy/pasting. And it's just an example because there are many.
Some people say that Scalaz was unreadable at the beginning, but 2 years later they find it great. I wonder where to start with Scalaz. The Scala validation seems the easiest part, but after that?
I agree that Scalaz is mostly undocumented. The problem is that it collects a lot of advanced concepts from Haskell (and the underlying mathematics) and documenting them all in detail would become writing a whole book about functional programming (and mathematics). So I believe Scalaz's approach is:
Let's have a look at your example: If you know Kleisli categories and how every monads gives rise to one, the definition is quite self-contained. If you don't, then KleisliCategory
has no use for you anyway.
(In my experience, Haskell is better for learning advanced concepts from functional programming. While Scala is far better than Java, it still drags around Java's OO/imperative heritage that clutters things a bit.)
Considering the Unicode symbols. Looking at sources it seems that they're used only as a syntactic sugar or at least they have a non-Unicode counterpart:
def ☆[M[_], A, B](f: A => M[B]): Kleisli[M, A, B] = kleisli(f) def η[F[_]](implicit p: Pure[F]): F[A] = pure def cokleisli[W[_], A, B](f: W[A] => B): Cokleisli[W, A, B] = ★(f)
So you can go without them, if you want.
Still, I'm not sure if having them in Scalaz is a good idea. It could make the code impossible to read for someone who lacks the proper fonts. I'd rather prefer pure ASCII symbols.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With