Question

I'm new to F# and haven't seen anywhere how to do the following correctly

let fun1 a b =
match a b with
| a + b > 0 -> fun2
| a + b < 0 -> fun3

I have to do this with pattern matching—for homework—but I don't know how to do it correctly. I thought I could be use tuples as follows:

let fun1 (a,b) =
match (a,b) with
| (a,b) when a + b > 0 -> fun2
| (a,b) when a + b < 0 -> fun3

But that doesn't work too. How do I proceed?

Was it helpful?

Solution

You have the right idea, you just forgot that indentation matters in F#. Adding spaces makes you solution work:

let fun1 (a,b) =  
    match (a,b) with
    | (a,b) when a + b > 0 -> fun2
    | (a,b) when a + b < 0 -> fun3

This actually patterns matches twice, so we might want to rewrite it:

let fun1 t = function 
    | (a,b) when a + b > 0 -> fun2
    | (a,b) when a + b < 0 -> fun3

The compiler/interpreter will let this go through, but with a warning:

warning FS0025: Incomplete pattern matches on this expression.

I'll leave getting rid of that as an exercise :-)

PS. Good of you to be upfront about this being homework.

OTHER TIPS

Søren Debois is correct. Here are a few other notes:

  1. a and b are already in scope, so you don't need to match against them, you can match against anything:

    let fun1 (a,b) =
        match () with
        | () when a + b > 0 -> fun2
        | () when a + b < 0 -> fun3
    
  2. For that reason, an using an if statement might be more idiomatic.

  3. You're clearly missing the case when a + b = 0; note that the compiler always assumes that a when clause might not cover anything, so you'll still get a warning that some cases may be unhandled even if you add a | () when a + b = 0 -> ... case; you'd need to do just | () -> ... or | _ -> ... instead.

  4. There's a built-in shortcut for definitions of the form let f <pattern> = match <same pattern> with |..., which is let f = function |.... You'd use it like:

    let fun1 = function
    | (a,b) when a + b > 0 -> fun2
    | ...
    

    Note that now a and b aren't bound by the function definition, so the idea from my first note doesn't apply and you have to introduce them in the pattern.

You can add in the match clause:

let fun2() = ()
let fun3() = ()
let fun1 a b =
    match (a+b) with
        | res when res > 0 -> fun2
        | res when res < 0 -> fun3
        | _ -> raise (new System.NotImplementedException())

Cover all cases of your pattern, as good practice :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top