Last active
September 20, 2019 12:11
-
-
Save dlidstrom/68cf244ccf3170dab9e612b6df541be4 to your computer and use it in GitHub Desktop.
Mix of result and applicative
This file contains hidden or 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
| module Result = | |
| let bind f = function | |
| | Ok x -> f x | |
| | Error x -> Error x | |
| let map f = function | |
| | Ok x -> Ok(f x) | |
| | Error err -> Error err | |
| let apply fResult xResult = | |
| match fResult, xResult with | |
| | Ok f, Ok x -> Ok(f x) | |
| | Ok _, Error x -> Error x | |
| | Error f, Ok _ -> Error f | |
| | Error f, Error x -> Error(List.concat [ f; x ]) | |
| let (<!>) = Result.map | |
| let (<*>) = Result.apply | |
| type ResultBuilder() = | |
| member this.Bind(m, f) = Result.bind f m | |
| member this.Return(x) = Ok x | |
| let result = new ResultBuilder() | |
| /// mix of monad and applicative | |
| type Username = Username of string | |
| module Username = | |
| let create u = | |
| if String.length u > 10 | |
| then Error ["Too long"] | |
| else Ok (Username u) | |
| let value (Username s) = s | |
| type Email = Email of string | |
| module Email = | |
| let create s = | |
| if String.length s > 10 | |
| then Error ["Wrong email"] | |
| else Ok (Email s) | |
| let value (Email s) = s | |
| let login u e = | |
| let (Username u) = u | |
| let (Email e) = e | |
| [|u; e|] |> String.concat "/" | |
| // short circuit any step that returns Error | |
| let xx = result { | |
| // collects all intermediate results | |
| // into one Ok (login successfully called) | |
| // or Error (one or more intermediate errors) | |
| let! l = | |
| login | |
| <!> (Username.create "1234567890") | |
| <*> (Email.create "1234567890") | |
| let! u = Username.create "abc" | |
| return u | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment