Scala Maybe
I wrote a Maybe (a lazy Option[T]) that I can use in Scala.
Scala Maybe
… because I wanted a lazy variant of Option[+T].
I had a use case in mind at the time, but, since then; I’ve taken another approach.
Since writing this, I’ve found an explanation of Monads that “groks” with me and multiple other places where “lazy is better” and I preffer (my) Maybe[T] over Option[T].
package peterlavalle
/**
    * like Option[+A] but lazy
    */
trait Maybe[+T] {
    /**
        * however we're implemented; ensure that any operations leading up to now are only called "once"
        */
    def cache: Maybe[T]
    /**
        * Apply some operation to the value, and, return a new monad.
        *
        * this is (more likely) lazy
        **/
    def call[V](operation: T => V): Maybe[V]
    /**
        * bind it like a monad ... but ... not lazy
        */
    def bind[V](operation: T => Maybe[V]): Maybe[V]
    /**
        * if we're empty; produce the other one
        */
    def otherwise[E >: T](them: => Maybe[E]): Maybe[E]
    /**
        * produce/convert this to an eager Option[T] in preparation for reading or matching it.
        *
        * This is (kind of) a hack
        */
    def some: Option[T]
    final def |[V](that: T => Maybe[V]): Maybe[V] = bind(that)
    final def : Maybe[V] = call(that)
    final def ?[E >: T](them: => Maybe[E]): Maybe[E] = otherwise(them)
}
object Maybe {
    def apply[T](read: => T): Maybe[T] =
        new Maybe[T] {
            override lazy final val cache: Maybe[T] = {
                lazy val data: T = read
                apply(data)
            }
            override lazy final val some: Option[T] = Some(read)
            override final def otherwise[E >: T](them: => Maybe[E]): Maybe[E] = this
            override final def bind[V](map: T => Maybe[V]): Maybe[V] =
                map(read)
            override final def call[V](map: T => V): Maybe[V] =
                Maybe {
                    map(read)
                }
        }
    def unapply[T](arg: Maybe[T]): Option[T] = arg.some
    case object Nope extends Maybe[Nothing] {
        override final val cache: Maybe[Nothing] = this
        override final val some: Option[Nothing] = None
        override final def bind[V](map: Nothing => Maybe[V]): Maybe[V] = Nope
        override final def call[V](map: Nothing => V): Maybe[V] = Nope
        override final def otherwise[E >: Nothing](them: => Maybe[E]): Maybe[E] = them
    }
}