Here is an almost direct translation, which, I believe, should answer your question. It is not completely straightforward because it does not use the types of classes that are present in the form of a template in Scala, because in the current case it will only have super simple things for no real reason.
case class LJ[A]( session : A ) { // See it as Haskell "fmap" def map[B]( f : A => B ) : LJ[B] = LJ( f( session ) ) // See it as Haskell ">>=" def flatMap[B]( f : A => LJ[B] ) : LJ[B] = f( session ) } type SimpleLJ = LJ[String] def auth( a : String, b : String ) : SimpleLJ = ??? def readFeed( a : String ) : SimpleLJ = ??? def closeFeed( a : String ) : SimpleLJ = ??? def proceed : SimpleLJ = auth("123", "456").flatMap(readFeed).flatMap(closeFeed) // Same as above but using a for-comprehension, which is // used as a replacement for Haskell "do"-block def proceed2 : SimpleLJ = for { a <- auth("123", "456") b <- readFeed(a) c <- closeFeed(b) } yield c
This solution demonstrates the classic object-oriented approach. With this approach, you cannot use the return function encapsulated in an LJ type, because you end up working at a different level, and not on the type, like using types, but in an instance of the type. Thus, the constructor of the case LJ class becomes the equivalent of return .
source share