def handleTransfer
(req
: TransferRequest
): Either
[Err, Result
] = { u1 <- req.user1.lookup(db).nestError
u2 <- req.user2.lookup(db).earlyResult { e =>
Result(s"Cannot find ${req.user2}: $e")
}
depositor <- u2.checkAccess(u1).earlyResult { _ =>
Result(s"$u2 has not given you deposit access")
}
withdrawal <- u1.withdraw(req.amount).nestError
conf <- depositor.accept(withdrawal).nestError
Result(s"You transferred $withdrawal to $u2, confirmation number $conf")
}
resultNested.joinLeft
}
def nestError
: Either
[Either
[A, Nothing
], B
] = either.left.map(Left(_))
def earlyResult
[C
](errorToResult
: A
=> C
): Either
[Either
[Nothing, C
], B
] = either.left.map(a => Right(errorToResult(a)))
}
}
def checkAccess
(that
: User
): Either
[Err, User
] = ??? def withdraw
(amount
: Double
): Either
[Err, Double
] = ??? def accept
(amount
: Double
): Either
[Err, Int
] = ??? }
def lookup
(db
: Any
): Either
[Err, User
] = ??? }
case class TransferRequest
(user1
: UserName, user2
: UserName, amount
: Double
)
b2JqZWN0IE1haW4gZXh0ZW5kcyBBcHAgewogIHZhbCBkYiA9ICIiCiAgZGVmIGhhbmRsZVRyYW5zZmVyKHJlcTogVHJhbnNmZXJSZXF1ZXN0KTogRWl0aGVyW0VyciwgUmVzdWx0XSA9IHsKICAgIHZhbCByZXN1bHROZXN0ZWQgPSBmb3IgewogICAgICB1MSA8LSByZXEudXNlcjEubG9va3VwKGRiKS5uZXN0RXJyb3IKICAgICAgdTIgPC0gcmVxLnVzZXIyLmxvb2t1cChkYikuZWFybHlSZXN1bHQgeyBlID0+CiAgICAgICAgUmVzdWx0KHMiQ2Fubm90IGZpbmQgJHtyZXEudXNlcjJ9OiAkZSIpCiAgICAgIH0KICAgICAgZGVwb3NpdG9yIDwtIHUyLmNoZWNrQWNjZXNzKHUxKS5lYXJseVJlc3VsdCB7IF8gPT4KICAgICAgICBSZXN1bHQocyIkdTIgaGFzIG5vdCBnaXZlbiB5b3UgZGVwb3NpdCBhY2Nlc3MiKQogICAgICB9CiAgICAgIHdpdGhkcmF3YWwgPC0gdTEud2l0aGRyYXcocmVxLmFtb3VudCkubmVzdEVycm9yCiAgICAgIGNvbmYgPC0gZGVwb3NpdG9yLmFjY2VwdCh3aXRoZHJhd2FsKS5uZXN0RXJyb3IKICAgIH0geWllbGQgewogICAgICBSZXN1bHQocyJZb3UgdHJhbnNmZXJyZWQgJHdpdGhkcmF3YWwgdG8gJHUyLCBjb25maXJtYXRpb24gbnVtYmVyICRjb25mIikKICAgIH0KICAgIHJlc3VsdE5lc3RlZC5qb2luTGVmdAogIH0KCiAgaW1wbGljaXQgY2xhc3MgTGVmdE5lc3RpbmdFaXRoZXJbQSwgQl0oZWl0aGVyOiBFaXRoZXJbQSwgQl0pIHsKICAgIGRlZiBuZXN0RXJyb3I6IEVpdGhlcltFaXRoZXJbQSwgTm90aGluZ10sIEJdID0KICAgICAgZWl0aGVyLmxlZnQubWFwKExlZnQoXykpCgogICAgZGVmIGVhcmx5UmVzdWx0W0NdKGVycm9yVG9SZXN1bHQ6IEEgPT4gQyk6IEVpdGhlcltFaXRoZXJbTm90aGluZywgQ10sIEJdID0KICAgICAgZWl0aGVyLmxlZnQubWFwKGEgPT4gUmlnaHQoZXJyb3JUb1Jlc3VsdChhKSkpCiAgfQp9CgpjYXNlIGNsYXNzIEVycihtc2c6IFN0cmluZykKY2FzZSBjbGFzcyBSZXN1bHQobXNnOiBTdHJpbmcpCmNsYXNzIFVzZXIoKSB7CiAgZGVmIGNoZWNrQWNjZXNzKHRoYXQ6IFVzZXIpOiBFaXRoZXJbRXJyLCBVc2VyXSA9ID8/PwogIGRlZiB3aXRoZHJhdyhhbW91bnQ6IERvdWJsZSk6IEVpdGhlcltFcnIsIERvdWJsZV0gPSA/Pz8KICBkZWYgYWNjZXB0KGFtb3VudDogRG91YmxlKTogRWl0aGVyW0VyciwgSW50XSA9ID8/Pwp9CmNsYXNzIFVzZXJOYW1lKCkgewogIGRlZiBsb29rdXAoZGI6IEFueSk6IEVpdGhlcltFcnIsIFVzZXJdID0gPz8/Cn0KY2FzZSBjbGFzcyBUcmFuc2ZlclJlcXVlc3QodXNlcjE6IFVzZXJOYW1lLCB1c2VyMjogVXNlck5hbWUsIGFtb3VudDogRG91YmxlKQo=