Skip to content

Instantly share code, notes, and snippets.

@CraftyFella
Last active June 24, 2020 21:27
Show Gist options
  • Save CraftyFella/330c3aea37675725636682f86d3a1841 to your computer and use it in GitHub Desktop.
Save CraftyFella/330c3aea37675725636682f86d3a1841 to your computer and use it in GitHub Desktop.
type Person =
{ FirstName: string
MiddleInitial: string option
LastName: string }
module String50 =
let create (thing: string) =
if thing = null then Error "Its null" else Ok thing
module Result =
let valueOrException result =
match result with
| Ok result -> result
| Error err -> failwithf "oops %A" err
let isOk result =
match result with
| Ok _ -> true
| _ -> false
let isError result =
match result with
| Error _ -> true
| _ -> false
let getOk result =
match result with
| Ok value -> value
| _ -> failwithf "Can't get value as it's an error"
let getError result =
match result with
| Error value -> value
| _ -> failwithf "Can't get error as it's an Ok"
let mapAll fn (array: Result<'a, 'b> list) =
if array |> List.forall isOk then
array
|> List.map getOk
|> Ok
else
array
|> List.filter isError
|> List.map getError
|> Error
|> Result.map fn
let original =
let firstName =
match (String50.create "John") with
| Ok name -> name
| Error err -> failwith (sprintf "oops %A" err)
let initial =
match (String50.create "P") with
| Ok name -> name
| Error err -> failwith (sprintf "oops %A" err)
let lastName =
match (String50.create "Smith") with
| Ok name -> name
| Error err -> failwith (sprintf "oops %A" err)
{ FirstName = firstName
MiddleInitial = Some initial
LastName = lastName }
let extractValueOrBlowUpHelper =
let firstName = String50.create "John" |> Result.valueOrException
let initial = String50.create "P" |> Result.valueOrException
let lastName = String50.create "Smith" |> Result.valueOrException
{ FirstName = firstName
MiddleInitial = Some initial
LastName = lastName }
type ResultBuilder() =
member __.Return(x) = Ok x
member __.Bind(m, f) = Result.bind f m
let result = new ResultBuilder()
let computationExpression =
result {
let! firstName = String50.create "John"
let! initial = String50.create "P"
let! lastName = String50.create "Smith"
return { FirstName = firstName
MiddleInitial = Some initial
LastName = lastName }
}
|> Result.valueOrException
let bindAndMap =
String50.create "John"
|> Result.bind (fun firstName ->
String50.create "P"
|> Result.bind (fun initial ->
String50.create "Smith"
|> Result.map (fun lastName ->
{ FirstName = firstName
MiddleInitial = Some initial
LastName = lastName })))
|> Result.valueOrException
let captureAllErrors f i l =
[ String50.create f
String50.create i
String50.create l ]
|> Result.mapAll (function
| [ firstName; initial; lastName ] ->
{ FirstName = firstName
MiddleInitial = Some initial
LastName = lastName })
let dump value = printfn "%A" value
[<EntryPoint>]
let main argv =
original |> dump
extractValueOrBlowUpHelper |> dump
computationExpression |> dump
bindAndMap |> dump
captureAllErrors "John" "P" "Smith"
|> Result.valueOrException
|> dump
captureAllErrors "John" null null |> dump
0
{ FirstName = "John"
MiddleInitial = Some "P"
LastName = "Smith" }
{ FirstName = "John"
MiddleInitial = Some "P"
LastName = "Smith" }
{ FirstName = "John"
MiddleInitial = Some "P"
LastName = "Smith" }
{ FirstName = "John"
MiddleInitial = Some "P"
LastName = "Smith" }
{ FirstName = "John"
MiddleInitial = Some "P"
LastName = "Smith" }
Error ["Its null"; "Its null"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment