---
# System prepended metadata

title: Untitled

---

Implement a minimal `Option` that has `map` and `flatMap`.
```scala
import scala.{Option => _}
// implement here

sealed trait Option[+Input] {
    def map[Output](predicate: Input => Output): Option[Output] = 
          this match {
              case Some(value) => Some(predicate(value))
              case None => None 
          }
            
    
    def flatMap[Output](predicate: Input => Option[Output]): Option[Output]= 
          this match {
              case Some(value) => predicate(value)
              case None => None 
          }
    
    def fold[Output](default: => Output, predicate: Input => Output): Output = {
        this match {
              case Some(value) => predicate(value)
              case None => default 
          }
    }
}

val o: Option[String] = Some("Hello")
o.fold(5 / 0, _.length)  // 5

case class Some[Input](value: Input) extends Option[Input]

case object None extends Option[Nothing]


val maybeName: Option[String] = ???
maybeName.fold("Anonymous", s => s)

val o1: Option[String] = Some("hello")
val o2: Option[Int] = o1.map(s => s.length)
val o3: Option[Char] = o1.flatMap(s => s.headOption)

val noneInt: Option[Int] = None
val noneString: Option[String] = None

sealed trait Animal
case object Dog extends Animal
Dog <: Animal
Option[Dog] <: Option[Animal] // <--- covariant

val maybeDog: Option[Dog] = ???

def pet(maybeAnimal: Option[Animal]): ???
pet(maybeDog)


```