0

I am reading example about monad transformers in scalaz. Here is a piece of code:

scala> def myName(step: String): Reader[String, String] = Reader {step + ", I am " + _}
myName: (step: String)scalaz.Reader[String,String]

scala> def localExample: Reader[String, (String, String, String)] = for {
         a <- myName("First")
         b <- myName("Second") >=> Reader { _ + "dy"}
         c <- myName("Third")
       } yield (a, b, c)
localExample: scalaz.Reader[String,(String, String, String)]

scala> localExample("Fred")
res0: (String, String, String) = (First, I am Fred,Second, I am Freddy,Third, I am Fred)

How does it happen, that localExample can take a parameter? Oo There is not any parameters list in definition localExample: Reader[String, (String, String, String)] just return type is specified. Also the same question about myName function, it also has more function parameters then mentioned in its definition.

Cherry
  • 31,309
  • 66
  • 224
  • 364

1 Answers1

0

The key is in the return type that is specified, which is an instance of the Reader monad. Roughly, the reader monad is like a wrapper around a function from - in the case of myName - String to String, so it is a bit like a function defined as:

def myName(step: String): String => String

For localExample, the return type is now a "wrapper around a function from String to Triple of String" (quotes used because this is something of a simplified sense of what the Reader monad is).

In both cases, the return type is - sort of - a function that can take a (String) parameter with which to generate a final result, and it is this sort-of-a function that is taking the parameter passed to localExample in the call localExample("Fred"). Essentially like calling localExample().apply("Fred").

There is more to monads like the Reader than just the above (which I'm not sure I feel expert enough to explain properly right now), but hopefully that's enough to answer your question.

Shadowlands
  • 14,994
  • 4
  • 45
  • 43