Gaurang Shah
Gaurang Shah

Reputation: 12900

How to use scala types Either or Option properly

I am a newbie in scala. And what I understand is, scala discourage to use try, catch, finally block. Rather it promotes the Option, Try and Either` types.

I want to understand how to use them properly in following case.

Function to Read property file

  def getSourcePath(properties: Properties): Path = {
    val dataFileURI: String = properties.getProperty("dataFileURI")
    val srcPath = new Path(dataFileURI)
    srcPath
  }

Function That uses value from getSourcePath

  val srcPath = getSourcePath(properties)
  def getDataFileName(srcPath: Path, auditID: String): String = {
    val dataFileName: String = srcPath.getName + "_" + auditID
    dataFileName
  }

GetSourcePath that returns Either


  def getSourcePath(properties: Properties): Either[FileSystemError, Path] = {
    try{
      val dataFileURI: String = properties.getProperty("dataFileURI")
      val srcPath = new Path(dataFileURI)
      Right(srcPath)  
    }catch{
      case exception: Exception => Left(FileSystemError("Not able to get dataFileURI"))
    }

getDataFileName to use Either.

def getDataFileName(srcPath: Either[FileSystemError, Path], auditID: String): Either[FileSystemError, String] = {
    srcPath match {
      case Right(srcPath) => Right(srcPath.getName + "_" + auditID)
      case Left(srcPath) => Left(srcPath)
    }
  }

However, This is just like passing exception further in methods. And doing pattern match for each argument looks an overkill, If I have 3-4 arguments.

Seems like I have not fully understand this types.

Upvotes: 0

Views: 88

Answers (1)

Allen Han
Allen Han

Reputation: 1163

Here is how I would write the code. I would use a Try monad, because it is the most concise. Either works too, but you have to use an explicit error type, and that makes things more verbose. So I would stick with Try.

def getSourcePath(properties: Properties): Try[Path] = 
  Try(new Path(properties.getProperty("dataFileURI")))

def getDataFileName(srcPath: Try[Path], auditID: String): Try[String] = 
  srcPath.map(_.getName + "_" + auditID)

If you want to convert to Option, call toOption on the Try monad that is returned from either of the functions.

If you have questions about how the code works, I can answer in the comments section

Upvotes: 3

Related Questions