Skip to content

Instantly share code, notes, and snippets.

@dlidstrom
Last active September 20, 2019 12:11
Show Gist options
  • Select an option

  • Save dlidstrom/68cf244ccf3170dab9e612b6df541be4 to your computer and use it in GitHub Desktop.

Select an option

Save dlidstrom/68cf244ccf3170dab9e612b6df541be4 to your computer and use it in GitHub Desktop.

Revisions

  1. dlidstrom revised this gist Sep 20, 2019. 1 changed file with 11 additions and 13 deletions.
    24 changes: 11 additions & 13 deletions Result.fs
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ module Result =
    | 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 ])
    | Error f, Error x -> Error(f @ x)

    let (<!>) = Result.map
    let (<*>) = Result.apply
    @@ -24,24 +24,22 @@ type ResultBuilder() =
    let result = new ResultBuilder()

    /// mix of monad and applicative
    type Username = Username of string
    module Username =
    let create u =
    type Username = private Username of string
    with
    static member 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 =
    member this.value = match this with Username s -> s
    type Email = private Email of string
    with
    static member 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 "/"
    member this.value = match this with Email s -> s
    let login (u : Username) (e : Email) =
    [|u.value; e.value|] |> String.concat "/"

    // short circuit any step that returns Error
    let xx = result {
  2. dlidstrom revised this gist Jun 7, 2019. 1 changed file with 13 additions and 16 deletions.
    29 changes: 13 additions & 16 deletions Result.fs
    Original file line number Diff line number Diff line change
    @@ -14,14 +14,15 @@ module Result =
    | Error f, Ok _ -> Error f
    | Error f, Error x -> Error(List.concat [ f; x ])

    let mapError f = function
    | Ok success -> Ok success
    | Error failure -> Error (f failure)

    let (>>=) m f = Result.bind f m
    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 =
    @@ -40,21 +41,17 @@ module Email =
    let login u e =
    let (Username u) = u
    let (Email e) = e
    [|u; e|] |> String.concat "-"

    type ResultBuilder() =
    //member this.Return(x) = Ok x
    member this.Bind(m, f) = Result.bind f m
    member this.Zero() = None
    member this.Return(x) = Ok x

    let result = new ResultBuilder()
    [|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 "12345678900")
    <*> (Email.create "12345678900")
    <!> (Username.create "1234567890")
    <*> (Email.create "1234567890")
    let! u = Username.create "abc"
    return u
    }
  3. dlidstrom revised this gist Jun 5, 2019. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions Result.fs
    Original file line number Diff line number Diff line change
    @@ -51,8 +51,10 @@ type ResultBuilder() =
    let result = new ResultBuilder()

    let xx = result {
    let username = Username.create "12345678900"
    let email = Email.create "12345678900"
    let! l = login <!> username <*> email
    return l
    let! l =
    login
    <!> (Username.create "12345678900")
    <*> (Email.create "12345678900")
    let! u = Username.create "abc"
    return u
    }
  4. dlidstrom created this gist Jun 5, 2019.
    58 changes: 58 additions & 0 deletions Result.fs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    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 mapError f = function
    | Ok success -> Ok success
    | Error failure -> Error (f failure)

    let (>>=) m f = Result.bind f m
    let (<!>) = Result.map
    let (<*>) = Result.apply

    /// 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 "-"

    type ResultBuilder() =
    //member this.Return(x) = Ok x
    member this.Bind(m, f) = Result.bind f m
    member this.Zero() = None
    member this.Return(x) = Ok x

    let result = new ResultBuilder()

    let xx = result {
    let username = Username.create "12345678900"
    let email = Email.create "12345678900"
    let! l = login <!> username <*> email
    return l
    }