Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.25 KB | None | 0 0
  1. // Given the following ADT:
  2.  
  3. sealed trait Status
  4. case object One extends Status
  5. case object Two extends Status
  6. case object Three extends Status
  7.  
  8. // They represent states. The natural progression, for this
  9. // example, is : One -> Two -> Three
  10.  
  11. // Then, the functions that'll be used in the below monadic chaining.
  12. // Observe that, it's possible, for an error to occur during f, g, or h
  13.  
  14. def f: Either[String, Status] = Right(One)
  15. def g(x: Status): Either[String, Status] = Right(Two)
  16. def h(x: Status): Either[String, Status] = Right(Three)
  17.  
  18. // Lastly, a for-comprehension that sequences through f, g and h.
  19. // Please ignore the fact that g and h both discard their input
  20.  
  21. scala> for {
  22. | a <- f.right
  23. | b <- g(a).right
  24. | c <- h(b).right
  25. | } yield c
  26. res4: scala.util.Either[String,Status] = Right(Three)
  27.  
  28. // From a type perspectice, `g` could return `Right(One)`. It would not
  29. // make sense per this domain (where all we know is One -> Two -> Three),
  30. // but of course One, Two and Three constitute Status.
  31.  
  32. // Can I do better here? I wrote a service that's similar to
  33. // this example, but I'm finding myself adding tests (with a test service)
  34. // where `g` returns Right(One). As a result, `h` will return
  35. // Left("Invalid state. Got One, but expected Two.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement