Last active
July 18, 2018 16:45
-
-
Save penland365/7dbb253ead01d34920aa02d1055d8b40 to your computer and use it in GitHub Desktop.
Discussion w/ Delila
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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