---
# System prepended metadata

title: Question

---

# Question
Implement the function `retrieveAddress` using the methods `getStreet1`, `getStreet2`, and `getStreet3` to create an `Address`.
```scala
case class Address(
  street1: String,
  street2: String,
  street3: Option[String]
)

sealed trait StreetError
case object MissingFirstStreet extends StreetError
case object MissingSecondStreet extends StreetError

def retrieveAddress: Option[Address] = {
    // TODO: Implement
    retrieveAddressOption(getStreet1) match {
        case Some(street1) => 
            Some(Address(
                street1,
                retrieveAddressOption(getStreet2),
                retrieveAddressOption(getStreet3))https://hackmd.io/@IgGTlSalToG4klwTIs-iTw/SyIGgnyv9/edit)
        case None => None
    }
}

def retrieveAddressOption(getter: () => String): Option[String] = {
    //Try(getter()).toOption
    Try(getter()) match {
        case Success(result) => Some(result)
        case Failure(_) => None
    }
}

val addr = retrieveAddress
addr match {
    case Right(address) => ...
    // If street1 is missing ???
    case Left(MissingFirstStreet) => cantCreateCustomer()
    // If street2 is missing ???
    case Left(MissingSecondStreet) => cantCreateCustomer() *> databaseError() *> pushMessageToCustomer()
}

// =======================================================================  
// 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