Skip to content

Instantly share code, notes, and snippets.

@penland365
Last active July 18, 2018 16:45
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 penland365/7dbb253ead01d34920aa02d1055d8b40 to your computer and use it in GitHub Desktop.
Save penland365/7dbb253ead01d34920aa02d1055d8b40 to your computer and use it in GitHub Desktop.
Discussion w/ Delila
// so you have something like this?
def respond(state: EngineState): Future[EngineState] = {
}
def respond(state: EngineState): Future[EngineState] = {
state.transaction match {
case Throw(_) =>
val transaction = Transaction(state.request.conversation, UnrecognisedCommand, Vector.empty)
val request = ResponseRequest(state.request.conversation, transaction)
ResponseService(request) transformF {
case Throw(e) => state.copy(response = Return("I'm sorry, could you repeat that?"))
case Return(response) => state.copy(response = Return(response.text))
}
case Return(transaction) =>
val request = ResponseRequest(state.request.conversation, transaction)
ResponseService(request) transformF {
case Throw(e) => state.copy(response = Throw(e))
case Return(response) =>
val updatedTransaction = ExecutionService.prompted(transaction, response.promptedContext)
state.copy(transaction = Return(updatedTransaction), response = Return(response.text))
}
}
}
// Two things
// Thing 1
// flatMap only operates on the "successful value" of a type. Let's use Either as an example:
def isPositive(x: Int): Either[String, Int] = {
if(x < 0) {
Left(s"Your number $x is less than 0")
} else {
Right(x)
}
}
def add2IfPositive(x: Int): Either[String, Int] = {
isPositive(x).flatMap(x => x + 2)
}
// a Monad is a "fail fast" operation, meaning that it continues along a computation until it fails, at which point it hits the ejection button
def addABunchIfPositive(x: Int) Either[String, Int] = {
isPositive(x).flatMap(y => y + 2)
.flatMap(y => y + 3)
.flatMap(y => y + 4)
}
def arbitraryDumbFunction(x: Int): Either[String, Int] = {
addABunchIfPositive(x).flatMap(y => y - 12)
.flatMap(addABunchIfPositive)
.flatMap(y => y + 2) // under our trivial example, this is not executed
}
val right: Either[String, Int] = addABunchIfPositive(2)
right == Right(11)
val left: Either[String, Int] = arbitraryDumbFunction(2)
left == Left("Your number -1 is less than zero")
// This is why we talk about Monads technically having a "Monadic Bind". Honestly, there is no such thing as a Monad.
// A type satisfies "has the property of a Monadic Bind" if the type can be "bound together" computationally in such a manner.
// Thing 2
// Types that posses the quaility of having monadic binds means that we can separate our concerns for successful and unsuccessful
// error handling. If you flatMap a function onto a type, you can always assume that the correct value has been passed in.
// Conversely, it also means that we can handle the failure mode seperately as well. Consider `recoverWith`, a function that is like
// flatMap but for failures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment