---
# System prepended metadata

title: Question

---

# Question
Implement the function `retrieveAddress` using the methods `getStreet1`, `getStreet2`, and `getStreet3` to create an `Address`.
```scala

sealed trait StreetError

object StreetError {
    case object MainAddressNotFound extends Throwable(s"street1 not found.")
    with StreetError
}

case class Address(
  street1: String,
  street2: Option[String],
  street3: Option[String]
)

def retrieveAddress: Option[Address] = {
    // TODO: Implement
    Try(getStreet1).toEither.left.map(_ => AddressNotFound(1)).map{ street1 =>
        val street2 = Try(getStreet2).toOption
        val street3 = Try(getStreet3).toOption
        Address(street1, street2, street3)
    }
    
    
    
    for {
        street1 <- Try(getStreet1).toEither.left.map(_ => AddressNotFound(1))
        street2 = Try(getStreet2).toOption
        street3 = Try(getStreet3).toOption
    } yield Address(street1, street2, street3)
}

// Caller
val eitherAddress = retrieveAddress
eitherAddress match {
    case Left(AddressNotFound(3)) => 
    case Left(AddressNotFound(-1)) => 
    case Right(..) =>
}

// =======================================================================  
// JAVA LIBRARY METHODS 
// =======================================================================
/**
  * Retrieves the main street address.
  * @throws RuntimeException if empty
  */
def getStreet1: String
/**
  * Retrieves additional street address line 2.
  * @throws RuntimeException if empty
  */
def getStreet2: String
/**
  * Retrieves additional street address line 3.
  * @throws RuntimeException if empty
  */
def getStreet3: String