Skip to content

Instantly share code, notes, and snippets.

@lispyclouds
Last active April 26, 2020 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lispyclouds/8d9526a39671f16b8ac830b68f604a81 to your computer and use it in GitHub Desktop.
Save lispyclouds/8d9526a39671f16b8ac830b68f604a81 to your computer and use it in GitHub Desktop.
Finally understood Types.
import scala.io.StdIn
// Result[+T] is a Monoid with bind as the join fn
sealed trait Result[+T] {
// makes this a Functor
def map[U](f: T => U): Result[U]
// bind hence a Monad
def flatMap[U](f: T => Result[U]): Result[U]
}
// unit
object Result {
// The `=> T` is SUPER IMPORTANT here!!
def apply[T](value: => T): Result[T] =
try Success(value) catch {
case e: Throwable => Failure(e)
}
}
final case class Success[+T](value: T) extends Result[T] {
override def flatMap[U](f: T => Result[U]): Result[U] = f(value)
// f(v) can safely blow up due to the construction of the unit
override def map[U](f: T => U): Result[U] = flatMap(v => Result[U](f(v)))
}
final case class Failure[+T](err: Throwable) extends Result[T] {
override def flatMap[U](f: T => Result[U]): Result[U] = this.asInstanceOf[Result[U]]
override def map[U](f: T => U): Result[U] = this.asInstanceOf[Result[U]]
}
object Monads {
def readInt(): Int = {
print("Enter a number: ")
StdIn.readInt
}
def safeReadAndAdd(prev: Int): Result[Int] = {
try {
Success(prev + readInt)
} catch {
case e: Throwable => Failure(e)
}
}
def main(args: Array[String]): Unit = {
val r1 = safeReadAndAdd(0)
.flatMap(safeReadAndAdd)
.flatMap(safeReadAndAdd)
.map(_ / readInt)
println(r1)
val r2 = for {
n1 <- safeReadAndAdd(0)
n2 <- safeReadAndAdd(n1)
n3 <- safeReadAndAdd(n2)
} yield n3 / readInt
println(r2)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment