---
# 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: Option[String],
  street3: Option[String],
    country: Option[String]
)

type MaybeStret = Option[String]


trait Error {
    msg: String
}

sealed trait AddressError extends Error{}

case object NonExistingStreetOne extends Error ("we need street1")
case class UnknwonException(error:e ) extends Error(e)

retrieveAddress match {
    case Left(_: NonExistingStreetOne) => 
}

def retrieveAddress: Either[Error, Address] = {
     val maybeStreet1 = Try(getStreet1) match {
        case RuntimeException => Left(NonExistingStreetOne)
        case street: String => Right(street)
        case e: Exception => Left(UnknwonException(e.getMessage))
        
    }
    val street2: Option[String] = getStreet(getStreet2)
    val street3: Option[String] = getStreet(getStreet3)
    
    val result: Error[Error, Address] = maybeStreet1.map(street1 => Address(street1, street2, street3))

    
    result
}

//tries to get a street with the input function and wraps it into an Option capturing possible exceptions
def getStreet( streetFunc: () => String): MaybeStret = Try(streetFunc).toOption 



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