Last active
July 1, 2024 13:27
-
-
Save lachezar/c4520bcd9589c0c7dcb4f5cf30638f66 to your computer and use it in GitHub Desktop.
Implementation of this exercise - https://fsharpforfunandprofit.com/posts/computation-expressions-bind/
This file contains 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 SafeModule = | |
let strToInt (str: string) : int option = | |
match System.Int32.TryParse str with | |
| true, i -> Some i | |
| _ -> None | |
type TestflowBuilder() = | |
member this.Bind(x: 'b option, f: 'b -> 'a option) : 'a option = Option.bind f x | |
member this.Return(x: 'a) : 'a option = Some x | |
let testflow = new TestflowBuilder() | |
let stringAddWorkflow x y z = | |
testflow { | |
let! a = strToInt x | |
let! b = strToInt y | |
let! c = strToInt z | |
return a + b + c | |
} | |
module UnsafeModule = | |
let strToInt (str: string) : int = int str | |
type TestflowBuilder() = | |
member this.Bind(x: 'b, f: 'b -> 'a) = f x | |
member this.Return(x: 'a) = x | |
let testflow = new TestflowBuilder() | |
let stringAddWorkflow x y z = | |
testflow { | |
let! a = strToInt x | |
let! b = strToInt y | |
let! c = strToInt z | |
return a + b + c | |
} | |
// Part 1 | |
let safeGood: int option = SafeModule.stringAddWorkflow "12" "3" "2" | |
let safeBad: int option = SafeModule.stringAddWorkflow "12" "xyz" "2" | |
printfn "%A and %A" safeGood safeBad | |
try | |
let unsafeGood: int = UnsafeModule.stringAddWorkflow "12" "3" "2" | |
printfn "%A" unsafeGood | |
let unsafeBad: int = UnsafeModule.stringAddWorkflow "12" "xyz" "2" | |
printfn "%A" unsafeBad | |
with e -> | |
printfn "An exception was thrown: %A" e | |
// Part 2 | |
let strAdd (str: string) (i: int) : int option = | |
SafeModule.testflow { | |
let! (x: int) = SafeModule.strToInt str | |
return x + i | |
} | |
let (>>=) (m: 'a option) (f: 'a -> 'b option) = SafeModule.testflow.Bind(m, f) | |
let good: int option = SafeModule.strToInt "1" >>= strAdd "2" >>= strAdd "3" | |
let bad: int option = SafeModule.strToInt "1" >>= strAdd "xyz" >>= strAdd "3" | |
printfn "Part 2: %A and %A" good bad |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment