Pattern matching by function call - f#

F# assigns function arguments via pattern matching. This is why
// ok: pattern matching of tuples upon function call
let g (a,b) = a + b
g (7,4)
works: The tuple is matched with (a,b) and a and b are available directly inside f.
Doing the same with discriminated unions would be equally beneficial, but I cannot get it to done:
// error: same with discriminated unions
type A =
| X of int * int
| Y of string
let f A.X(a, b) = a + b // Error: Successive patterns
// should be separated by spaces or tupled
// EDIT, integrating the answer:
let f (A.X(a, b)) = a + b // correct
f (A.X(7, 4))
Is pattern matching as part of the function call limited to tuples? Is there a way to do it with discriminated unions?

You need extra parens:
let f (A.X(a, b)) = a + b

Related

F# custom operator with 3 parameters

I found the following piece of code in the fantomas library for F#. I am having a hard time understanding this as an F# noob. From what I understand, it's a custom operator that takes 3 arguments, but why would an operator need 3 arguments? And what exactly is happening here?
/// Function composition operator
let internal (+>) (ctx: Context -> Context) (f: _ -> Context) x =
let y = ctx x
match y.WriterModel.Mode with
| ShortExpression infos when
infos
|> Seq.exists (fun x -> x.ConfirmedMultiline)
->
y
| _ -> f y
Here's an example of how fantomas uses this operator in ther CodePrinter module.
let short =
genExpr astContext e1
+> sepSpace
+> genInfixOperator "=" operatorExpr
+> sepSpace
+> genExpr astContext e2
Operators behave a lot like function names:
let (++) a b c d =
a + b + c + d
(++) 1 2 3 4
One difference is that operators can be used infix. An operator with more than 2 arguments allows infix only for the first 2 arguments:
// the following is equal:
let f = (++) 1 2 // like a function name
let f = 1 ++ 2 // with infix
f 50 60
I did not find how fantomas uses the operator you mention, would be curious, in particular since fantomas is a high profile f# project.
It might be instructive to compare this to the regular function composition operator, >>. The definition for this is:
let (>>) (f : a' -> b') (g : b' -> c') (x : a') =
g ( f x )
Esentially, it applies f to x, and then applies g to the result.
If we have the following functions:
let plusOne i = i + 1
let timesTwo j = j * 2
And apply it the following way:
let plusOneTimesTwo = plusOne >> timesTwo
What we're really doing is something like this:
let plusOneTimesTwo = (>>) plusOne timesTwo
When you don't supply all of the necessary arguments to a function (in this case, x), what you get is a function that takes the remaining arguments and then returns what the original function would return (this is partial application.) In this case, plusOneTimesTwo's function signature is now x : int -> int.
The example you've listed is essentially the same thing, but it's performing additional logic to determine whether it wants to apply the second function to the result y or to return it as-is.

How to invoke function using named parameter arguments in F#

How can I call F# functions by specifying the parameter names in the call site?
I've tried the following:
let add x y =
x + y
add (x = 10) (y = 10) // How to specify the name x and y when calling add?
But it gives this error:
error FS0039: The value or constructor 'x' is not defined.
You can't invoke let-bound functions with named arguments. It's allowed only for methods in classes
Named arguments are allowed only for methods, not for let-bound functions, function values, or lambda expressions.
Documentation
Technically you can declare static class and use method from it, but I think it's wrong. Just wrong. Don't do it
[<AbstractClass; Sealed>]
type MathOperations =
static member Add (x, y) = x + y
open type MathOperations
[<EntryPoint>]
let main argv =
Add(x = 3, y = 4)
|> printfn "%d"
0
This issue confused me too in the beginning. Functions and methods are not alike.
Functions are curried by default to support partial application. They don't support named argument calls.
Methods support named arguments using a single tuple for all parameters.
(EDIT after Bent Tranberg's comment) Methods also support curried declaration member _.Add x y = x + y and even mixed style declaration member _.Add3 (x: int, y: int) (z: int) = x + y + z but these methods cannot be called using named arguments o.Add3 (y=2, x=1) 3 💥
In JavaScript, named arguments can be simulated using an object literal as argument. Let's try do the same in F#, using tuple or record:
1. Tuple: Method arguments are provided all at once with a tuple. Can we use a tuple as function parameter and call the function with named arguments? No ❌
let add (x, y) = x + y
add (x = 1, y = 2) // 💥
// ~ Error FS0039: The value or constructor 'x' is not defined
2. Anonymous record: not possible due to actual limitation in anonymous record deconstruction ❌
let add {| X = x; Y = y |} = x + y
// ~~ Error FS0010: Unexpected symbol '{|' in pattern
3. Named record: ⚠️
type AddParam = { x: int; y: int }
let add { x = x; y = y } = x + y
add { x = 1; y = 2 }
This way, we are able to name the arguments and choose their order ({ y = 2; x = 1 } but we loose the partial application. So it's not idiomatic→ should be avoided, unless in specific cases.
4. Single-case DU: 👌
If we care only about the argument naming but not about the argument re-ordering, we can use discriminated unions, especially single-case DU:
type XParam = X of int
type YParam = Y of int
let add (X x) (Y y) = x + y
add (X 1) (Y 2)
This way, the arguments appeared as named and partial application is preserved.
--
EDIT
☝ I don't recommend creating single-case DU just to simulate named arguments ! It's the other way around: when we have single-case DU in our domain model, we know that they will bring their semantic to document the code and help reasoning about the code, in this case more or less like named arguments.
You have to understand function calling in F#, which is different from traditional imperative languages like C#.
let f x y = x + y // defines a function with this signature:
val f : x:int -> y:int -> int
// this function is full or partially applicable:
let g = f 4 // partial application
val g : (int -> int) // a new function that evaluates f 4 y
g 10
val it : int = 14
In traditional languages functions have a single set of arguments. In F# you express such traditional functions with multiple arguments into a function with a tuple argument:
let f (x, y) = x + y
val f : x:int * y:int -> int
// partial application is no longer possible, since the arguments have been packed into a single tuple
Such traditional tuple-argument functions do not allow calls with named arguments:
f (x=3, y=5) // interpreted as = test expressions
F# language design is sound here, and (x=3, y=5) does not express the desired tuple.
F# has named arguments since a while (this was added in the last years sometime). This is limited to member functions however. Once you translate your function into a member it works:
type A() =
static member f (x,y) = x + y
A.f(y=3, x=4) // yes, this works!

Why active patterns behave this way?

I found this code in the excellent book F# Design Patterns by Gene Belitski:
let (| `` I'm active pattern `` |) x = x + 2
let (`` I'm active pattern `` y) = 40
(*
val ( |`` I'm active pattern ``| ) : x:int -> int
val y : int = 42
*)
The author recognizes that this is
"a slightly mind boggling example that becomes clear if you remember that the let binding of a value is a corner case of pattern matching based data disassembling, so I'm active pattern gets applied to input argument 40 and binds the result 42 to x."
I don't get it. Why does I'm active pattern gets applied to 40, given that 40 is on the right-hand side? Intuitively I would guess that y = 38, not 42, looking at the expression let (`` I'm active pattern `` y) = 40 as an implicit function.
Can anyone explain?
That's what makes active patterns special; with a normal function the definition let f x = ... mirrors the application of f: you can mentally evaluate f e by substituting e for x in the definition.
By contrast, with an active pattern let (|P|) x = ..., when you see let (P y) = e the fresh identifier y will get the result of applying the body of the definition to e.
This is perhaps easier to see with an active pattern where the result type differs from the input type:
let (|StringValue|) (i:int) = sprintf "%i" i
let (StringValue s) = 1 // s is of type string, with value "1"

Curried Arguments in Discriminated Unions

I have a discriminated union like this:
type A = |B | C of int*A
I have to pattern match like this (the parenthesis appear to be needed):
match x with
| B -> printfn "B"
| C (i,a) -> printfn "%A, %A" i a
Is there a way to instead match like this with something like an active pattern:
match x with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a
And if not how come F# is designed such that this matching with curried arguments doesn't work and it instead forces you to use a tuple?
Edit: This was inspired by the F# list in which you can use h::t without any tupling or anything like that. And the source code is like:
type List<'T> =
| ([]) : 'T list
| (::) : Head: 'T * Tail: 'T list -> 'T list
I think examining the definitions of a curried function and an active pattern will make this clear for you.
Curried function:
A function which takes multiple parameters but which allows you to pass them in one at a time in order to return a function which does the same thing but takes one fewer parameters. Example:
let add a b = a + b
//val add : a:int -> b:int -> int
let add5 = add 5
//val add5 : (int -> int)
Active Pattern:
A way of applying pattern matching where the matching can be done using parsing or other complex logic. Takes one parameter and returns the result of the parsing. So input -> single return parameter.
//Example taken from https://fsharpforfunandprofit.com/posts/convenience-active-patterns/
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true,int) -> Some(int)
| _ -> None
val ( |Int|_| ) : str:string -> int option
Since the whole point of currying a function is to be able to partially apply the function, the concept simply makes no sense when applied to the result of an active pattern.
Put another way, the result of an active pattern can't be "curried" because you can only curry functions and the result of an active pattern is data which is not a function. In your example, 'C (i,a)' is defining the return type of the Active Pattern case, not a function call.
You cannot have whitespace as delimiter between bound patterns, because neither union cases nor active patterns support this. Syntax as per the F# spec:
6.9.8 Evaluating Union Case
Case(e1,…,en)
7.2.3 Active Patterns
(|CaseName|) arg1 ... argn inp
(|CaseName|_|) arg1 ... argn inp
So it's necessarily one tupled argument for a union case; and n+1 arguments for the banana function, of which n arguments are parameters. Only the last argument binds to the pattern. Consider:
type X = B | C
let (|C|) a b = C (a, b)
let i = 42
match C with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a // prints 42, (42, C)
The case C in your discriminated union has a value of a tuple type (int * A).
The (i,a) part of your pattern matching isn't a parameter, it's matching the i to the int part and the a to the A part.
You could equally match with C x and x would hold a tuple of (int * A).

"summing" functions in F#

I have a list of functions in F# which are all of type (float -> float -> float -> float). I want to do some kind of fold on the sequence to get a single function which returns the sum of all of the functions.
For instance, I could pass the values 1.0, 2.0, and 3.0 to every function in the list, and get a return value from each one. Then I could compute the sum of all of these values. However, I want to generalize this.
I know how to do this recursively, but I feel like it should be doable in one line. Is there a concise way to accomplish this task?
The solution by #Lee is a one liner you're looking for. If you wanted to save a few characters, you can use List.sumBy which first applies a given function to an element of the list (similar to List.map) and then sums the result (just like List.sum):
let sumAll (fs:(_ -> _ -> _ -> float) list) a b c =
List.sumBy (fun f -> f a b c) fs
Both this and Lee's version uses type annotations to specify that the functions in the list return float. This is needed, because otherwise the compiler does not know what kind of numbers you want to sum using List.sum (floats, integers, etc.). This ambiguity needs to be resolved to compile the function.
Alternatively, you could mark the function as inline and then it would be inlined when you call it (and it would work for multiple different numeric types). You can also pass the fs parameter as the last one and use partial function application:
let inline sumAll a b c = List.sumBy (fun f -> f a b c)
Now you can call it using pipelining as follows: fs |> sumAll 1 2 3.
let sumAll (fs: (float -> float -> float -> float) list) a b c = List.map (fun f -> f a b c) fs |> Seq.sum
The answers by #Lee and #Tomas are great, but there is a shorter way.
If you can afford passing (a, b, c) as a triple upon invocation:
let inline sumAll() = (|||>) >> List.sumBy
// usage
let predicates =
[
fun a b c -> a
fun a b c -> b * 42.0 - c
]
let ret1 = predicates |> sumAll()(1.0, 2.0, 3.0)
It will be also generic:
let predicates2 =
[
fun a b c -> c - 10
fun a b c -> a + c * 42
]
let ret2 = predicates2 |> sumAll()(1, 2, 3)
A more readable way which supports curried arguments:
let sumAllCurried a b c = (a,b,c) |> (|||>) |> List.sumBy<_, float>
// usage
let ret3 = predicates |> sumAllCurried 1.0 2.0 3.0
Note, I'm using a type parameter on List.sumBy since it looks shorter than typing an entire type specification for f.

Resources