2

I'm trying to wrap my head around how to accomplish the following task in F#. The following is a simplified C# pseudocode equivalent I'm looking to replicate.

var x = await GetXAsync();
if (x == null) return "not found";
var y = await GetYAsync(x);
return y;

My initial F# version looks something like:

task {
    let! x = GetXAsync()
    match x with
    | None -> // need to return a hard-coded value here
    | Some x` -> 
                 let! y = GetYAsync(x`)
                 // More code
                 // return some value based on y here
}

Obviously this is terrible, but I'm unsure of how to proceed. Should I attempt a full ROP style of programming here, or is there something simpler?

Brian Vallelunga
  • 9,869
  • 15
  • 60
  • 87
  • 2
    With just two values, `x` and `y`, I don't think there's a need for a full-fledged ROP solution. What you have looks just fine to me; I don't agree with you that it is "terrible". Sometimes the simple solution is best. – rmunn Jul 23 '19 at 05:58
  • Well, is it just that piece of code, or does the pattern continues drawing a stairway? – Gus Jul 23 '19 at 06:13

1 Answers1

2

In your example, you are returning the "not found" string to indicate that something went wrong from a function that otherwise returns strings. I would not do this, because it will be hard to distinguish between the case where everything worked and the case where it did not.

If the fact that GetXAsync returns null is something that indicates a failure, then I'd just use exceptions. F# async has a nice support for propagating those and you can catch them using try .. with. There is nothing wrong with using exceptions in F# to handle exceptional situations!

exception InvalidX of string

let GetXAsync() = async { 
  // whetever code that calculates 'failed' and 'result' goes here
  if failed then raise (InvalidX "not found")
  return result }

Then you can just call the functions and exceptions get propagated automatically.

async {
  let! x = GetXAsync() 
  let! y = GetYAsync(x)
  return y }
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • 1
    Thanks for the response. The example code was really just to show the structure and I should have been more clear about that. In reality, I'm coding a handler for Giraffe and either need to return a 404 or some JSON data. I'll work on making this more clear. I was pretty tired when I wrote it. BTW, your book is great! – Brian Vallelunga Jul 24 '19 at 01:53